Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/AddressExpr.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/AggregateDecl.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/ApplicationExpr.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -17,5 +17,4 @@
 #include <list>                  // for list
 #include <map>                   // for _Rb_tree_const_iterator, map, map<>:...
-#include <memory>                // for unique_ptr
 #include <ostream>               // for operator<<, ostream, basic_ostream
 #include <string>                // for operator<<, string, char_traits
@@ -43,10 +42,4 @@
 }
 
-ParamEntry::~ParamEntry() {
-	delete actualType;
-	delete formalType;
-	delete expr;
-}
-
 ParamEntry::ParamEntry( ParamEntry && other ) :
 		decl( other.decl ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ), inferParams( std::move( other.inferParams ) ) {
@@ -58,7 +51,4 @@
 ParamEntry & ParamEntry::operator=( ParamEntry && other ) {
 	if ( &other == this ) return *this;
-	delete actualType;
-	delete formalType;
-	delete expr;
 	decl = other.decl;
 	actualType = other.actualType;
@@ -86,9 +76,4 @@
 }
 
-ApplicationExpr::~ApplicationExpr() {
-	delete function;
-	deleteAll( args );
-}
-
 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Application of" << std::endl << indent+1;
Index: src/SynTree/ArrayType.cc
===================================================================
--- src/SynTree/ArrayType.cc	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/ArrayType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/AttrType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Attribute.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Attribute.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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.cc
===================================================================
--- src/SynTree/BaseSyntaxNode.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
+++ src/SynTree/BaseSyntaxNode.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+// BaseSyntaxNode.cc --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thr Mar 22 14:10:00 2018
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thr Mar 22 14:10:00 2018
+// Update Count     : 1
+//
+
+#include "BaseSyntaxNode.h"
+
+#include <iostream>
+
+std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {
+	if ( node ) {
+		node->print( out );
+	} else {
+		out << "nullptr";
+	}
+	return out;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/BaseSyntaxNode.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -17,13 +17,14 @@
 
 #include "Common/CodeLocation.h"
+#include "Common/GC.h"
 #include "Common/Indenter.h"
+
 class Visitor;
 class Mutator;
 
-class BaseSyntaxNode {
-  public:
+class BaseSyntaxNode : public GC_Object {
+  friend class GcTracer;
+public:
 	CodeLocation location;
-
-	virtual ~BaseSyntaxNode() {}
 
 	virtual BaseSyntaxNode * clone() const = 0;
Index: src/SynTree/CommaExpr.cc
===================================================================
--- src/SynTree/CommaExpr.cc	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/CommaExpr.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/CompoundStmt.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Constant.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Constant.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -19,17 +19,17 @@
 #include <string>     // for string
 
-#include "BaseSyntaxNode.h"
 #include "Mutator.h"  // for Mutator
 #include "Visitor.h"  // for Visitor
 
+#include "Common/Indenter.h"  // for Indenter
+
 class Type;
 
-class Constant : public BaseSyntaxNode {
+class Constant {
   public:
 	Constant( Type * type, std::string rep, unsigned long long val );
 	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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/DeclStmt.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Declaration.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 );
@@ -85,9 +78,4 @@
 
 StaticAssertDecl::StaticAssertDecl( const StaticAssertDecl & other ) : Declaration( other ), condition( maybeClone( other.condition ) ), message( maybeClone( other.message ) )  {
-}
-
-StaticAssertDecl::~StaticAssertDecl() {
-	delete condition;
-	delete message;
 }
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Declaration.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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; }
@@ -88,6 +87,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; }
@@ -127,5 +125,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; }
@@ -157,5 +154,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; }
@@ -185,5 +181,4 @@
 	NamedTypeDecl( const std::string &name, Type::StorageClasses scs, Type *type );
 	NamedTypeDecl( const NamedTypeDecl &other );
-	virtual ~NamedTypeDecl();
 
 	Type *get_base() const { return base; }
@@ -220,5 +215,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; }
@@ -269,6 +263,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; }
@@ -354,5 +347,4 @@
 	AsmDecl( AsmStmt *stmt );
 	AsmDecl( const AsmDecl &other );
-	virtual ~AsmDecl();
 
 	AsmStmt *get_stmt() { return stmt; }
@@ -373,5 +365,4 @@
 	StaticAssertDecl( Expression * condition, ConstantExpr * message );
 	StaticAssertDecl( const StaticAssertDecl & other );
-	virtual ~StaticAssertDecl();
 
 	virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
Index: src/SynTree/DeclarationWithType.cc
===================================================================
--- src/SynTree/DeclarationWithType.cc	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/DeclarationWithType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Expression.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -59,5 +59,4 @@
 Expression::~Expression() {
 	delete env;
-	delete result;
 }
 
@@ -81,6 +80,4 @@
 ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
 }
-
-ConstantExpr::~ConstantExpr() {}
 
 void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
@@ -127,8 +124,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 );
@@ -157,9 +150,4 @@
 }
 
-SizeofExpr::~SizeofExpr() {
-	delete expr;
-	delete type;
-}
-
 void SizeofExpr::print( std::ostream &os, Indenter indent) const {
 	os << "Sizeof Expression on: ";
@@ -183,9 +171,4 @@
 }
 
-AlignofExpr::~AlignofExpr() {
-	delete expr;
-	delete type;
-}
-
 void AlignofExpr::print( std::ostream &os, Indenter indent) const {
 	os << "Alignof Expression on: ";
@@ -203,8 +186,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 {
@@ -224,8 +203,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 ";
@@ -241,6 +216,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 ";
@@ -259,10 +232,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;
 }
 
@@ -287,8 +254,4 @@
 
 CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {
-}
-
-CastExpr::~CastExpr() {
-	delete arg;
 }
 
@@ -312,8 +275,4 @@
 }
 
-KeywordCastExpr::~KeywordCastExpr() {
-	delete arg;
-}
-
 const std::string & KeywordCastExpr::targetString() const {
 	static const std::string targetStrs[] = {
@@ -340,8 +299,4 @@
 
 VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
-}
-
-VirtualCastExpr::~VirtualCastExpr() {
-	delete arg;
 }
 
@@ -368,9 +323,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;
@@ -399,9 +349,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;
@@ -419,9 +364,4 @@
 		Expression( other ), function( maybeClone( other.function ) ) {
 	cloneAll( other.args, args );
-}
-
-UntypedExpr::~UntypedExpr() {
-	delete function;
-	deleteAll( args );
 }
 
@@ -472,6 +412,4 @@
 }
 
-NameExpr::~NameExpr() {}
-
 void NameExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Name: " << get_name();
@@ -486,9 +424,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;
 }
 
@@ -506,10 +439,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;
 }
 
@@ -549,8 +476,4 @@
 ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
 	set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
-	delete callExpr;
-	deleteAll( tempDecls );
-	deleteAll( returnDecls );
-	deleteAll( dtors );
 }
 
@@ -577,8 +500,4 @@
 }
 
-ConstructorExpr::~ConstructorExpr() {
-	delete callExpr;
-}
-
 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
 	os <<  "Constructor Expression: " << std::endl << indent+1;
@@ -595,8 +514,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 {
@@ -625,13 +540,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() ) {
@@ -676,9 +585,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;
@@ -693,14 +598,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 {
@@ -720,8 +618,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 {
@@ -737,7 +631,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 {
@@ -754,7 +645,4 @@
 }
 DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {}
-DefaultArgExpr::~DefaultArgExpr() {
-	delete expr;
-}
 
 void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const {
@@ -766,15 +654,8 @@
 GenericExpr::Association::Association( Expression * expr ) : type( nullptr ), expr( expr ), isDefault( true ) {}
 GenericExpr::Association::Association( const Association & other ) : type( maybeClone( other.type ) ), expr( maybeClone( other.expr ) ), isDefault( other.isDefault ) {}
-GenericExpr::Association::~Association() {
-	delete type;
-	delete expr;
-}
 
 GenericExpr::GenericExpr( Expression * control, const std::list<Association> & assoc ) : Expression(), control( control ), associations( assoc ) {}
-GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {
-}
-GenericExpr::~GenericExpr() {
-	delete control;
-}
+GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {}
+GenericExpr::~GenericExpr() {}
 
 void GenericExpr::print( std::ostream & os, Indenter indent ) const {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Expression.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -41,6 +41,5 @@
 	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 && other );
-	~ParamEntry();
+	ParamEntry( ParamEntry&& other );
 	ParamEntry & operator=( const ParamEntry & other );
 	ParamEntry & operator=( ParamEntry && other );
@@ -55,4 +54,7 @@
 /// Expression is the root type for all expressions
 class Expression : public BaseSyntaxNode {
+  protected:
+	virtual ~Expression();
+
   public:
 	Type * result;
@@ -63,5 +65,4 @@
 	Expression();
 	Expression( const Expression & other );
-	virtual ~Expression();
 
 	Type *& get_result() { return result; }
@@ -94,5 +95,4 @@
 	ApplicationExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
 	ApplicationExpr( const ApplicationExpr & other );
-	virtual ~ApplicationExpr();
 
 	Expression * get_function() const { return function; }
@@ -116,5 +116,4 @@
 	UntypedExpr( Expression * function, const std::list<Expression *> & args = std::list< Expression * >() );
 	UntypedExpr( const UntypedExpr & other );
-	virtual ~UntypedExpr();
 
 	Expression * get_function() const { return function; }
@@ -141,5 +140,4 @@
 	NameExpr( std::string name );
 	NameExpr( const NameExpr & other );
-	virtual ~NameExpr();
 
 	const std::string & get_name() const { return name; }
@@ -162,5 +160,4 @@
 	AddressExpr( Expression * arg );
 	AddressExpr( const AddressExpr & other );
-	virtual ~AddressExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -181,5 +178,4 @@
 	LabelAddressExpr( const Label &arg );
 	LabelAddressExpr( const LabelAddressExpr & other );
-	virtual ~LabelAddressExpr();
 
 	virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
@@ -199,5 +195,4 @@
 	CastExpr( Expression * arg, void * ) = delete; // prevent accidentally passing pointers for isGenerated in the first constructor
 	CastExpr( const CastExpr & other );
-	virtual ~CastExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -220,5 +215,4 @@
 	KeywordCastExpr( Expression * arg, Target target );
 	KeywordCastExpr( const KeywordCastExpr & other );
-	virtual ~KeywordCastExpr();
 
 	const std::string & targetString() const;
@@ -237,5 +231,4 @@
 	VirtualCastExpr( Expression * arg, Type * toType );
 	VirtualCastExpr( const VirtualCastExpr & other );
-	virtual ~VirtualCastExpr();
 
 	Expression * get_arg() const { return arg; }
@@ -256,5 +249,4 @@
 	UntypedMemberExpr( Expression * member, Expression * aggregate );
 	UntypedMemberExpr( const UntypedMemberExpr & other );
-	virtual ~UntypedMemberExpr();
 
 	Expression * get_member() const { return member; }
@@ -278,5 +270,4 @@
 	MemberExpr( DeclarationWithType * member, Expression * aggregate );
 	MemberExpr( const MemberExpr & other );
-	virtual ~MemberExpr();
 
 	DeclarationWithType * get_member() const { return member; }
@@ -299,5 +290,4 @@
 	VariableExpr( DeclarationWithType * var );
 	VariableExpr( const VariableExpr & other );
-	virtual ~VariableExpr();
 
 	DeclarationWithType * get_var() const { return var; }
@@ -319,5 +309,4 @@
 	ConstantExpr( Constant constant );
 	ConstantExpr( const ConstantExpr & other );
-	virtual ~ConstantExpr();
 
 	Constant * get_constant() { return & constant; }
@@ -343,5 +332,4 @@
 	SizeofExpr( const SizeofExpr & other );
 	SizeofExpr( Type * type );
-	virtual ~SizeofExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -368,5 +356,4 @@
 	AlignofExpr( const AlignofExpr & other );
 	AlignofExpr( Type * type );
-	virtual ~AlignofExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -391,5 +378,4 @@
 	UntypedOffsetofExpr( Type * type, const std::string & member );
 	UntypedOffsetofExpr( const UntypedOffsetofExpr & other );
-	virtual ~UntypedOffsetofExpr();
 
 	std::string get_member() const { return member; }
@@ -412,5 +398,4 @@
 	OffsetofExpr( Type * type, DeclarationWithType * member );
 	OffsetofExpr( const OffsetofExpr & other );
-	virtual ~OffsetofExpr();
 
 	Type * get_type() const { return type; }
@@ -432,5 +417,4 @@
 	OffsetPackExpr( StructInstType * type );
 	OffsetPackExpr( const OffsetPackExpr & other );
-	virtual ~OffsetPackExpr();
 
 	StructInstType * get_type() const { return type; }
@@ -454,5 +438,4 @@
 	AttrExpr( const AttrExpr & other );
 	AttrExpr( Expression * attr, Type * type );
-	virtual ~AttrExpr();
 
 	Expression * get_attr() const { return attr; }
@@ -479,5 +462,4 @@
 	LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true );
 	LogicalExpr( const LogicalExpr & other );
-	virtual ~LogicalExpr();
 
 	bool get_isAnd() const { return isAnd; }
@@ -505,5 +487,4 @@
 	ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 );
 	ConditionalExpr( const ConditionalExpr & other );
-	virtual ~ConditionalExpr();
 
 	Expression * get_arg1() const { return arg1; }
@@ -528,5 +509,4 @@
 	CommaExpr( Expression * arg1, Expression * arg2 );
 	CommaExpr( const CommaExpr & other );
-	virtual ~CommaExpr();
 
 	Expression * get_arg1() const { return arg1; }
@@ -548,5 +528,4 @@
 	TypeExpr( Type * type );
 	TypeExpr( const TypeExpr & other );
-	virtual ~TypeExpr();
 
 	Type * get_type() const { return type; }
@@ -568,5 +547,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; }
@@ -590,4 +568,7 @@
 /// along with a set of copy constructor calls, one for each argument.
 class ImplicitCopyCtorExpr : public Expression {
+protected:
+	virtual ~ImplicitCopyCtorExpr();
+
 public:
 	ApplicationExpr * callExpr;
@@ -598,5 +579,4 @@
 	ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
 	ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other );
-	virtual ~ImplicitCopyCtorExpr();
 
 	ApplicationExpr * get_callExpr() const { return callExpr; }
@@ -620,5 +600,4 @@
 	ConstructorExpr( Expression * callExpr );
 	ConstructorExpr( const ConstructorExpr & other );
-	~ConstructorExpr();
 
 	Expression * get_callExpr() const { return callExpr; }
@@ -638,5 +617,4 @@
 	CompoundLiteralExpr( Type * type, Initializer * initializer );
 	CompoundLiteralExpr( const CompoundLiteralExpr & other );
-	virtual ~CompoundLiteralExpr();
 
 	Initializer * get_initializer() const { return initializer; }
@@ -675,5 +653,4 @@
 	UntypedTupleExpr( const std::list< Expression * > & exprs );
 	UntypedTupleExpr( const UntypedTupleExpr & other );
-	virtual ~UntypedTupleExpr();
 
 	std::list<Expression*>& get_exprs() { return exprs; }
@@ -692,5 +669,4 @@
 	TupleExpr( const std::list< Expression * > & exprs );
 	TupleExpr( const TupleExpr & other );
-	virtual ~TupleExpr();
 
 	std::list<Expression*>& get_exprs() { return exprs; }
@@ -710,5 +686,4 @@
 	TupleIndexExpr( Expression * tuple, unsigned int index );
 	TupleIndexExpr( const TupleIndexExpr & other );
-	virtual ~TupleIndexExpr();
 
 	Expression * get_tuple() const { return tuple; }
@@ -730,5 +705,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; }
@@ -750,5 +724,4 @@
 	StmtExpr( CompoundStmt * statements );
 	StmtExpr( const StmtExpr & other );
-	virtual ~StmtExpr();
 
 	CompoundStmt * get_statements() const { return statements; }
@@ -775,5 +748,4 @@
 	UniqueExpr( Expression * expr, long long idVal = -1 );
 	UniqueExpr( const UniqueExpr & other );
-	~UniqueExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -805,5 +777,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();
 };
 
@@ -815,5 +786,4 @@
 	UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts );
 	UntypedInitExpr( const UntypedInitExpr & other );
-	~UntypedInitExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -835,5 +805,4 @@
 	InitExpr( Expression * expr, Designation * designation );
 	InitExpr( const InitExpr & other );
-	~InitExpr();
 
 	Expression * get_expr() const { return expr; }
@@ -857,5 +826,4 @@
 	DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt );
 	DeletedExpr( const DeletedExpr & other );
-	~DeletedExpr();
 
 	virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); }
@@ -872,5 +840,4 @@
 	DefaultArgExpr( Expression * expr );
 	DefaultArgExpr( const DefaultArgExpr & other );
-	~DefaultArgExpr();
 
 	virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
@@ -892,5 +859,4 @@
 		Association( const Association & other );
 		Association & operator=( const Association & other ) = delete; // at the moment this isn't used, and I don't want to implement it
-		~Association();
 	};
 
@@ -900,5 +866,5 @@
 	GenericExpr( Expression * control, const std::list<Association> & assoc );
 	GenericExpr( const GenericExpr & other );
-	virtual ~GenericExpr();
+	~GenericExpr();
 
 	virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/FunctionDecl.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/FunctionType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -31,9 +31,4 @@
 	cloneAll( other.returnVals, returnVals );
 	cloneAll( other.parameters, parameters );
-}
-
-FunctionType::~FunctionType() {
-	deleteAll( returnVals );
-	deleteAll( parameters );
 }
 
Index: src/SynTree/GcTracer.h
===================================================================
--- src/SynTree/GcTracer.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
+++ src/SynTree/GcTracer.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -0,0 +1,166 @@
+//
+// 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 "Label.h"
+#include "Type.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) {}
+
+	// mark node and children
+
+	void previsit( BaseSyntaxNode * node ) {
+		// skip tree if already seen
+		if ( node->mark == gc.mark ) {
+			visit_children = false;
+			return;
+		}
+
+		// mark node
+		node->mark = gc.mark;
+	}
+
+	// add visits left out by PassVisitor
+
+	void postvisit( Constant* con ) {
+		maybeAccept( con->get_type(), *visitor );
+	}
+
+	void postvisit( AggregateDecl* decl ) {
+		acceptAll( decl->attributes, *visitor );
+	}
+
+	void postvisit( DeclarationWithType* decl ) {
+		maybeAccept( decl->asmName, *visitor );
+	}
+
+private:
+	void visit( InferredParams& inferParams ) {
+		for ( auto& entry : inferParams ) {
+			maybeAccept( entry.second.actualType, *visitor );
+			maybeAccept( entry.second.formalType, *visitor );
+			maybeAccept( entry.second.expr, *visitor );
+			visit( *entry.second.inferParams );
+		}
+	}
+
+public:
+	void postvisit( Expression* expr ) {
+		maybeAccept( expr->env, *visitor );
+		visit( expr->inferParams );
+	}
+
+	void postvisit( OffsetofExpr* expr ) {
+		postvisit( static_cast<Expression*>(expr) );
+		maybeAccept( expr->member, *visitor );
+	}
+
+	void postvisit( UniqueExpr* expr ) {
+		postvisit( static_cast<Expression*>(expr) );
+		maybeAccept( expr->object, *visitor );
+		maybeAccept( expr->var, *visitor );
+	}
+
+	void postvisit( UntypedExpr* expr ) {
+		postvisit( static_cast<Expression*>(expr) );
+		maybeAccept( expr->function, *visitor );
+	}
+
+	void postvisit( VariableExpr* expr ) {
+		postvisit( static_cast<Expression*>(expr) );
+		maybeAccept( expr->var, *visitor );  // not in PassVisitor because it causes cycle
+	}
+
+private:
+	void visit( Label& lbl ) {
+		acceptAll( lbl.get_attributes(), *visitor );
+		// maybeAccept( lbl.get_statement(), *visitor );  // introduces infinite loop in tracer
+	}
+
+public:
+	void postvisit( Statement* stmt ) {
+		for ( Label& l : stmt->labels ) {
+			visit( l );
+		}
+	}
+
+	void postvisit( BranchStmt* stmt ) {
+		postvisit( static_cast<Statement*>(stmt) );
+		visit( stmt->target );
+		maybeAccept( stmt->computedTarget, *visitor );
+	}
+
+	void postvisit( Type* type ) {
+		acceptAll( type->attributes, *visitor );
+	}
+
+	void postvisit( EnumInstType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->baseEnum, *visitor );
+	}
+
+	void postvisit( PointerType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->dimension, *visitor );
+	}
+
+	void postvisit( StructInstType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->baseStruct, *visitor );
+	}
+
+	void postvisit( TraitInstType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->baseTrait, *visitor );
+	}
+
+	void postvisit( TypeInstType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->baseType, *visitor );
+	}
+
+	void postvisit( UnionInstType* type ) {
+		postvisit( static_cast<Type*>(type) );
+		maybeAccept( type->baseUnion, *visitor );
+	}
+};
+
+/// Traces entire translation unit recursively
+static inline const GC& operator<< ( const GC& gc, const std::list<Declaration*>& translationUnit ) {
+	PassVisitor<GcTracer> tracer{ gc };
+	acceptAll( const_cast<std::list<Declaration*>&>( 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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Initializer.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Initializer.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/NamedTypeDecl.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/ObjectDecl.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/PointerType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/ReferenceToType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/ReferenceType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Statement.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 );
 }
 
@@ -129,8 +116,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: ";
@@ -148,11 +131,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;
 }
 
@@ -192,10 +168,4 @@
 }
 
-SwitchStmt::~SwitchStmt() {
-	delete condition;
-	// destroy statements
-	deleteAll( statements );
-}
-
 void SwitchStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Switch on condition: ";
@@ -216,9 +186,4 @@
 	Statement( other ), condition( maybeClone(other.condition ) ), _isDefault( other._isDefault ) {
 	cloneAll( other.stmts, stmts );
-}
-
-CaseStmt::~CaseStmt() {
-	delete condition;
-	deleteAll( stmts );
 }
 
@@ -251,9 +216,4 @@
 }
 
-WhileStmt::~WhileStmt() {
-	delete body;
-	delete condition;
-}
-
 void WhileStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "While on condition: " << endl ;
@@ -273,11 +233,4 @@
 		cloneAll( other.initialization, initialization );
 
-}
-
-ForStmt::~ForStmt() {
-	deleteAll( initialization );
-	delete condition;
-	delete increment;
-	delete body;
 }
 
@@ -319,9 +272,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;
 }
 
@@ -344,10 +292,4 @@
 }
 
-TryStmt::~TryStmt() {
-	delete block;
-	deleteAll( handlers );
-	delete finallyBlock;
-}
-
 void TryStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Try Statement" << endl;
@@ -378,9 +320,4 @@
 }
 
-CatchStmt::~CatchStmt() {
-	delete decl;
-	delete body;
-}
-
 void CatchStmt::print( std::ostream &os, Indenter indent ) const {
 	os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
@@ -405,8 +342,4 @@
 
 FinallyStmt::FinallyStmt( const FinallyStmt & other ) : Statement( other ), block( maybeClone( other.block ) ) {
-}
-
-FinallyStmt::~FinallyStmt() {
-	delete block;
 }
 
@@ -440,20 +373,4 @@
 	orelse .statement = other.orelse .statement->clone();
 	orelse .condition = other.orelse .condition->clone();
-}
-
-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;
 }
 
@@ -497,8 +414,4 @@
 	cloneAll( other.exprs, exprs );
 }
-WithStmt::~WithStmt() {
-	deleteAll( exprs );
-	delete stmt;
-}
 
 void WithStmt::print( std::ostream & os, Indenter indent ) const {
@@ -526,8 +439,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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Statement.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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; }
@@ -149,5 +145,4 @@
 			std::list<Statement *> initialization = std::list<Statement *>() );
 	IfStmt( const IfStmt &other );
-	virtual ~IfStmt();
 
 	std::list<Statement *> &get_initialization() { return initialization; }
@@ -172,5 +167,4 @@
 	SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
 	SwitchStmt( const SwitchStmt &other );
-	virtual ~SwitchStmt();
 
 	Expression *get_condition() { return condition; }
@@ -194,5 +188,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 *>() );
@@ -226,5 +219,4 @@
 	       Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
 	WhileStmt( const WhileStmt &other );
-	virtual ~WhileStmt();
 
 	Expression *get_condition() { return condition; }
@@ -251,5 +243,4 @@
 	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
 	ForStmt( const ForStmt &other );
-	virtual ~ForStmt();
 
 	std::list<Statement *> &get_initialization() { return initialization; }
@@ -304,5 +295,4 @@
 	ReturnStmt( Expression *expr );
 	ReturnStmt( const ReturnStmt &other );
-	virtual ~ReturnStmt();
 
 	Expression *get_expr() { return expr; }
@@ -325,5 +315,4 @@
 	ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
 	ThrowStmt( const ThrowStmt &other );
-	virtual ~ThrowStmt();
 
 	Kind get_kind() { return kind; }
@@ -347,5 +336,4 @@
 	TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
 	TryStmt( const TryStmt &other );
-	virtual ~TryStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -374,5 +362,4 @@
 	           Expression *cond, Statement *body );
 	CatchStmt( const CatchStmt &other );
-	virtual ~CatchStmt();
 
 	Kind get_kind() { return kind; }
@@ -396,5 +383,4 @@
 	FinallyStmt( CompoundStmt *block );
 	FinallyStmt( const FinallyStmt &other );
-	virtual ~FinallyStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -423,5 +409,4 @@
 	WaitForStmt();
 	WaitForStmt( const WaitForStmt & );
-	virtual ~WaitForStmt();
 
 	std::vector<Clause> clauses;
@@ -452,5 +437,4 @@
 	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
 	WithStmt( const WithStmt & other );
-	virtual ~WithStmt();
 
 	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
@@ -468,5 +452,4 @@
 	DeclStmt( Declaration *decl );
 	DeclStmt( const DeclStmt &other );
-	virtual ~DeclStmt();
 
 	Declaration *get_decl() const { return decl; }
@@ -490,5 +473,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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TupleExpr.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TupleType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Type.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -63,9 +63,4 @@
 }
 
-Type::~Type() {
-	deleteAll( forall );
-	deleteAll( attributes );
-}
-
 // These must remain in the same order as the corresponding bit fields.
 const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Type.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -141,5 +141,4 @@
 	Type( const Qualifiers & tq, const std::list< Attribute * > & attributes );
 	Type( const Type & other );
-	virtual ~Type();
 
 	Qualifiers & get_qualifiers() { return tq; }
@@ -263,5 +262,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; }
@@ -293,5 +291,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; }
@@ -321,5 +318,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; }
@@ -354,5 +350,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; }
@@ -378,5 +373,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; }
@@ -505,5 +499,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;
@@ -527,5 +520,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; }
@@ -551,5 +543,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;
@@ -585,5 +576,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; }
@@ -608,5 +598,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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TypeDecl.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TypeExpr.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TypeSubstitution.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -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 );
 }
 
@@ -161,5 +144,4 @@
 		Type * newtype = i->second->clone();
 		newtype->get_qualifiers() |= inst->get_qualifiers();
-		delete inst;
 		// Note: need to recursively apply substitution to the new type because normalize does not substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
 		return newtype->acceptMutator( *visitor );
@@ -173,5 +155,4 @@
 	} else {
 		subCount++;
-		delete nameExpr;
 		return i->second->clone();
 	} // if
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TypeSubstitution.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -35,5 +35,4 @@
 	TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
 	TypeSubstitution( const TypeSubstitution &other );
-	virtual ~TypeSubstitution();
 
 	TypeSubstitution &operator=( const TypeSubstitution &other );
@@ -60,4 +59,5 @@
 	void normalize();
 
+	void accept( Visitor& v ) { v.visit( this ); }
 	TypeSubstitution * acceptMutator( Mutator & m ) { return m.mutate( this ); }
 
@@ -101,8 +101,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 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/TypeofType.cc	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -29,8 +29,4 @@
 }
 
-TypeofType::~TypeofType() {
-	delete expr;
-}
-
 void TypeofType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/Visitor.h	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -126,4 +126,6 @@
 
 	virtual void visit( Attribute * attribute ) = 0;
+
+	virtual void visit( TypeSubstitution * sub ) = 0;
 };
 
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 999c700597272d91cda35041cfc950bf0526243b)
+++ src/SynTree/module.mk	(revision 184557ed94d1cdbdc6fd685e497e5375f8968a96)
@@ -48,4 +48,5 @@
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
+       SynTree/BaseSyntaxNode.cc \
        SynTree/DeclReplacer.cc
 
