Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/CodeGen/CodeGenerator.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -1150,13 +1150,4 @@
 unsigned Indenter::tabsize = 2;
 
-std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {
-	if ( node ) {
-		node->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/CodeGen/FixMain.cc
===================================================================
--- src/CodeGen/FixMain.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/CodeGen/FixMain.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -29,5 +29,5 @@
 namespace CodeGen {
 	bool FixMain::replace_main = false;
-	std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
+	FunctionDecl* FixMain::main_signature = nullptr;
 
 	template<typename container>
@@ -41,5 +41,5 @@
 			SemanticError(functionDecl, "Multiple definition of main routine\n");
 		}
-		main_signature.reset( functionDecl->clone() );
+		main_signature = functionDecl;
 	}
 
Index: src/CodeGen/FixMain.h
===================================================================
--- src/CodeGen/FixMain.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/CodeGen/FixMain.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -40,5 +40,5 @@
 	  private:
   		static bool replace_main;
-		static std::unique_ptr<FunctionDecl> main_signature;
+		static FunctionDecl* main_signature;
 	};
 };
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/CodeGen/FixNames.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -16,5 +16,4 @@
 #include "FixNames.h"
 
-#include <memory>                  // for unique_ptr
 #include <string>                  // for string, operator!=, operator==
 
@@ -47,12 +46,12 @@
 	std::string mangle_main() {
 		FunctionType* main_type;
-		std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,
-																   main_type = new FunctionType( Type::Qualifiers(), true ), nullptr )
-				};
+		FunctionDecl* mainDecl = new FunctionDecl{ 
+			"main", Type::StorageClasses(), LinkageSpec::Cforall, 
+			main_type = new FunctionType{ Type::Qualifiers(), true }, nullptr };
 		main_type->get_returnVals().push_back(
 			new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
 		);
 
-		auto && name = SymTab::Mangler::mangle( mainDecl.get() );
+		auto && name = SymTab::Mangler::mangle( mainDecl );
 		// std::cerr << name << std::endl;
 		return std::move(name);
@@ -60,7 +59,7 @@
 	std::string mangle_main_args() {
 		FunctionType* main_type;
-		std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,
-																   main_type = new FunctionType( Type::Qualifiers(), false ), nullptr )
-				};
+		FunctionDecl* mainDecl = new FunctionDecl{
+			"main", Type::StorageClasses(), LinkageSpec::Cforall,
+			main_type = new FunctionType{ Type::Qualifiers(), false }, nullptr };
 		main_type->get_returnVals().push_back(
 			new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )
@@ -77,5 +76,5 @@
 		);
 
-		auto&& name = SymTab::Mangler::mangle( mainDecl.get() );
+		auto&& name = SymTab::Mangler::mangle( mainDecl );
 		// std::cerr << name << std::endl;
 		return std::move(name);
Index: src/CodeGen/Generate.cc
===================================================================
--- src/CodeGen/Generate.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/CodeGen/Generate.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -41,5 +41,5 @@
 		void cleanTree( std::list< Declaration * > & translationUnit ) {
 			PassVisitor<TreeCleaner> cleaner;
-			filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
+			filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); } );
 			mutateAll( translationUnit, cleaner );
 		} // cleanTree
@@ -79,5 +79,5 @@
 				}
 				return false;
-			}, false );
+			} );
 		}
 
@@ -85,5 +85,4 @@
 			Statement * callStmt = nullptr;
 			std::swap( stmt->callStmt, callStmt );
-			delete stmt;
 			return callStmt;
 		}
Index: src/Common/GC.cc
===================================================================
--- src/Common/GC.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
+++ src/Common/GC.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -0,0 +1,163 @@
+//
+// 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.
+//
+// GC.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 "GC.h"
+
+#include "Common/PassVisitor.h"
+
+#include "SynTree/GcTracer.h"
+
+#include <algorithm>
+#include <cassert>
+
+GC& GC::get() {
+	static GC gc;
+	return gc;
+}
+
+GC::GC() : gens(1), static_roots(), mark(false), g(0) {
+	gens[0].reserve(70000);
+}
+
+GC::~GC() {
+	for ( unsigned i = 0; i <= g; ++i ) {
+		for ( GC_Object* o : gens[i] ) {
+			delete o;
+		}
+	}
+}
+
+const GC& GC::operator<< (const GC_Object* obj) const {
+	if( obj )
+	{
+		if( obj->mark != this->mark ) {
+			obj->mark = this->mark;
+			obj->trace( *this );
+		}
+	}
+	return *this;
+}
+
+// build with flag GC_TRAP to compile in a breakpoint on register and sweep of a dynamically 
+// chosen object. Process to use:
+//     break GC::register_object
+//     run
+//     set variable GC_TRAP_OBJ = <target>
+//     disable <first breakpoint>
+//     continue
+#ifdef GC_TRAP
+#include <csignal>
+
+/// Set to object to check in debugger
+void* GC_TRAP_OBJ = nullptr;
+#endif
+
+void GC::register_object(GC_Object* obj) {
+	#ifdef GC_TRAP
+		if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
+	#endif
+	gens[g].push_back(obj);
+	obj->mark = !this->mark;  // initialize as un-marked
+}
+
+void GC::register_static_root(BaseSyntaxNode* root) {
+	static_roots.push_back(root);
+}
+
+GC_Guard GC::new_generation() {
+	if ( ++g == gens.size() ) { gens.emplace_back(); }  // ensure new generation available
+	mark = !mark;  // switch mark so aged young objects will still be unmarked in old
+	return { *this, g };
+}
+
+void GC::trace_static_roots() {
+	PassVisitor<GcTracer> tracer{ *this };
+	for ( BaseSyntaxNode* root : static_roots ) {
+		root->accept( tracer );
+	}
+}
+
+void GC::collect_young() {
+	// get generations and decrement generation
+	assert(g > 0 && "Cannot collect_young without young generation");
+	Generation& young = gens[g];
+	Generation& old = gens[--g];
+
+	// ensure static roots traced
+	trace_static_roots();
+
+	// collect young gen
+	for ( GC_Object*& obj : young ) {
+		if ( obj->mark != mark ) {
+			#ifdef GC_TRAP
+				if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
+			#endif
+			delete obj;
+			obj = nullptr;
+		}
+	}
+	
+	// move uncollected elements into old gen
+	auto end_live = std::remove( young.begin(), young.end(), nullptr );
+	old.insert( old.end(), young.begin(), end_live );
+	
+	// clear young gen and reset mark to return to old generation mark
+	young.clear();
+	mark = !mark;
+}
+
+void GC::collect() {
+	// ensure not called when young gen is active
+	assert(g == 0 && "Cannot do old collection when young generation is active");
+	Generation& old = gens[0];
+
+	// ensure static roots traced
+	trace_static_roots();
+
+	// collect old gen
+	for ( GC_Object*& obj : old ) {
+		if ( obj->mark != mark ) {
+			#ifdef GC_TRAP
+				if ( obj == GC_TRAP_OBJ ) std::raise(SIGTRAP);
+			#endif
+			delete obj;
+			obj = nullptr;
+		}
+	}
+
+	// clear collected elements
+	old.erase( std::remove( old.begin(), old.end(), nullptr ), old.end() );
+
+	// reset mark
+	mark = !mark;
+}
+
+GC_Object::GC_Object() {
+	GC::get().register_object( this );
+}
+
+GC_Object::GC_Object( const GC_Object& ) {
+	GC::get().register_object( this );
+}
+
+GC_Object::GC_Object( GC_Object&& ) {
+	GC::get().register_object( this );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/GC.h
===================================================================
--- src/Common/GC.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
+++ src/Common/GC.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -0,0 +1,156 @@
+//
+// 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.
+//
+// GC.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 <cassert>
+#include <vector>
+
+class GC_Object;
+class BaseSyntaxNode;
+class GC_Guard;
+
+/// Manually traced and called garbage collector
+class GC {
+	friend class GcTracer;
+	friend class GC_Guard;
+
+	/// Collects the youngest generation, placing survivors in previous generation.
+	/// Young generation objects cannot be kept alive by pointers from older generation.
+	/// Older generation is used for subsequent new objects.
+	void collect_young();
+public:
+	/// Gets singleton GC instance
+	static GC& get();
+
+	/// Traces a traceable object
+	const GC& operator<< (const GC_Object*) const;
+
+	/// Adds a new object to garbage collection
+	void register_object(GC_Object*);
+
+	/// Adds an object to the set of static roots
+	void register_static_root(BaseSyntaxNode*);
+
+	/// Start new generation for subsequent new objects
+	GC_Guard new_generation();
+
+	/// Traces all static roots
+	void trace_static_roots();
+
+	/// Collects oldest generation; use oldest generation afterward.
+	/// Error if currently using younger generation
+	void collect();
+
+	/// Collects all contained objects
+	~GC();
+
+private:
+	GC();
+
+	using Generation = std::vector<GC_Object*>;
+	std::vector<Generation> gens;  ///< Set of generations; always at least one
+
+	using StaticRoots = std::vector<BaseSyntaxNode*>;
+	StaticRoots static_roots;      ///< Set of static-lifetime roots
+
+	bool mark;                     ///< The current collection's mark bit
+	unsigned g;                    ///< The current number generation in use
+};
+
+/// Cleanup object for young generation
+class GC_Guard {
+	friend class GC;
+
+	GC& gc;      ///< GC associated with
+	unsigned g;  ///< Generation constructed for
+
+	GC_Guard( GC& gc, unsigned g ) : gc(gc), g(g) {}
+
+public:
+	~GC_Guard() {
+		assert( gc.g == g && "collecting current generation" );
+		gc.collect_young();
+	}
+};
+
+/// Use young generation until next collection
+inline GC_Guard new_generation() { return GC::get().new_generation(); }
+
+// /// no-op default trace
+// template<typename T>
+// inline const GC& operator<< (const GC& gc, const T& x) { return gc; }
+
+inline void traceAll(const GC&) {}
+
+/// Marks all arguments as live in current generation
+template<typename T, typename... Args>
+inline void traceAll(const GC& gc, T& x, Args&... xs) {
+	gc << x;
+	traceAll(gc, xs...);
+}
+
+/// Traces roots without collecting
+template<typename... Args>
+inline void trace(Args&... roots) {
+	GC& gc = GC::get();
+	traceAll(gc, roots...);
+}
+
+/// Traces roots and collects other elements; should not be any young generations live
+template<typename... Args>
+inline void collect(Args&... roots) {
+	GC& gc = GC::get();
+	traceAll(gc, roots...);
+	gc.collect();
+}
+
+/// Makes a new expression as a static root
+template<typename T, typename... Args>
+inline T* new_static_root( Args&&... args ) {
+	T* root = new T( std::forward<Args>(args)... );
+	GC::get().register_static_root( root );
+	return root;
+}
+
+/// Class that is managed by the GC
+class GC_Object {
+	friend class GC;
+protected:
+	mutable bool mark;
+
+	// Override default constructors to ensure clones are registered and properly marked
+	GC_Object();
+
+	GC_Object(const GC_Object&);
+
+	GC_Object(GC_Object&&);
+
+	GC_Object& operator= (const GC_Object&) { /* do not assign mark */ return *this; }
+
+	GC_Object& operator= (GC_Object&&) { /* do not assign mark */ return *this; }
+
+	// Ensure subclasses can be deleted by garbage collector
+	virtual ~GC_Object() {}
+
+	/// override to trace any child objects
+	virtual void trace(const GC&) const {}
+};
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Common/PassVisitor.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -151,7 +151,9 @@
 	virtual void visit( Subrange * subrange ) override final;
 
-	virtual void visit( Constant * constant ) override final;
+	virtual void visit( Constant * constant ) final;
 
 	virtual void visit( Attribute * attribute ) override final;
+
+	virtual void visit( TypeSubstitution * sub ) final;
 
 	virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final;
@@ -249,5 +251,5 @@
 	virtual Subrange * mutate( Subrange * subrange ) override final;
 
-	virtual Constant * mutate( Constant * constant ) override final;
+	virtual Constant * mutate( Constant * constant ) final;
 
 	virtual Attribute * mutate( Attribute * attribute ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Common/PassVisitor.impl.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -38,5 +38,5 @@
 	MUTATE_END( type, node );      \
 
-
+#include "Common/GC.h"
 
 template<typename T>
@@ -397,10 +397,10 @@
 			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-			static ObjectDecl func(
+			static ObjectDecl* func = new_static_root<ObjectDecl>(
 				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
 				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
 				nullptr
 			);
-			indexerAddId( &func );
+			indexerAddId( func );
 			maybeAccept_impl( node->type, *this );
 			maybeAccept_impl( node->statements, *this );
@@ -427,10 +427,10 @@
 			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-			static ObjectDecl func(
+			static ObjectDecl* func = new_static_root<ObjectDecl>(
 				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
 				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
 				nullptr
 			);
-			indexerAddId( &func );
+			indexerAddId( func );
 			maybeMutate_impl( node->type, *this );
 			maybeMutate_impl( node->statements, *this );
@@ -1209,4 +1209,5 @@
 	indexerScopedAccept( node->result, *this );
 
+	// xxx - not quite sure why this doesn't visit( node->function );
 	for ( auto expr : node->args ) {
 		visitExpression( expr );
@@ -2615,4 +2616,18 @@
 // TypeSubstitution
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( TypeSubstitution * node ) {
+	VISIT_START( node );
+
+	for ( auto & p : node->typeEnv ) {
+		indexerScopedAccept( p.second, *this );
+	}
+	for ( auto & p : node->varEnv ) {
+		indexerScopedAccept( p.second, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
 	MUTATE_START( node );
Index: src/Common/module.mk
===================================================================
--- src/Common/module.mk	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Common/module.mk	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk --
+## module.mk -- 
 ##
 ## Author           : Richard C. Bilson
@@ -18,4 +18,5 @@
        Common/UniqueName.cc \
        Common/DebugMalloc.cc \
+       Common/GC.cc \
        Common/Assert.cc \
        Common/Heap.cc
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Common/utility.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -190,12 +190,9 @@
 
 template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args >
-void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) {
+void filter( Container< E *, Args... > & container, UnaryPredicate pred ) {
 	auto i = begin( container );
 	while ( i != end( container ) ) {
 		auto it = next( i );
 		if ( pred( *i ) ) {
-			if ( doDelete ) {
-				delete *i;
-			} // if
 			container.erase( i );
 		} // if
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Concurrency/Keywords.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -19,4 +19,5 @@
 #include <string>                  // for string, operator==
 
+#include "Common/GC.h"             // for new_static_root
 #include "Common/PassVisitor.h"    // for PassVisitor
 #include "Common/SemanticError.h"  // for SemanticError
@@ -206,13 +207,8 @@
 		StructDecl* dtor_guard_decl = nullptr;
 
-		static std::unique_ptr< Type > generic_func;
+		static Type* generic_func;
 	};
 
-	std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(
-		new FunctionType(
-			noQualifiers,
-			true
-		)
-	);
+	Type* MutexKeyword::generic_func = new_static_root<FunctionType>( noQualifiers, true );
 
 	//-----------------------------------------------------------------------------
@@ -288,10 +284,7 @@
 			// convert (thread &)t to (thread_desc &)*get_thread(t), etc.
 			if( !type_decl ) SemanticError( cast, context_error );
-			Expression * arg = cast->arg;
-			cast->arg = nullptr;
-			delete cast;
 			return new CastExpr(
 				UntypedExpr::createDeref(
-					new UntypedExpr( new NameExpr( getter_name ), { arg } )
+					new UntypedExpr( new NameExpr( getter_name ), { cast->arg } )
 				),
 				new ReferenceType(
@@ -318,5 +311,4 @@
 		StructDecl * forward = decl->clone();
 		forward->set_body( false );
-		deleteAll( forward->get_members() );
 		forward->get_members().clear();
 
@@ -382,6 +374,4 @@
 			fixupGenerics(main_type, decl);
 		}
-
-		delete this_decl;
 
 		declsToAddBefore.push_back( forward );
Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Concurrency/Waitfor.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -137,6 +137,4 @@
 		StructDecl          * decl_acceptable = nullptr;
 		StructDecl          * decl_monitor    = nullptr;
-
-		static std::unique_ptr< Type > generic_func;
 
 		UniqueName namer_acc = "__acceptables_"s;
@@ -476,6 +474,4 @@
 		}
 
-		delete setter;
-
 		return new VariableExpr( timeout );
 	}
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ControlStruct/ExceptTranslate.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -104,13 +104,13 @@
 		// Types used in translation, make sure to use clone.
 		// void (*function)();
-		FunctionType try_func_t;
+		FunctionType * try_func_t;
 		// void (*function)(int, exception);
-		FunctionType catch_func_t;
+		FunctionType * catch_func_t;
 		// int (*function)(exception);
-		FunctionType match_func_t;
+		FunctionType * match_func_t;
 		// bool (*function)(exception);
-		FunctionType handle_func_t;
+		FunctionType * handle_func_t;
 		// void (*function)(__attribute__((unused)) void *);
-		FunctionType finally_func_t;
+		FunctionType * finally_func_t;
 
 		StructInstType * create_except_type() {
@@ -125,9 +125,9 @@
 			handler_except_decl( nullptr ),
 			except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ),
-			try_func_t( noQualifiers, false ),
-			catch_func_t( noQualifiers, false ),
-			match_func_t( noQualifiers, false ),
-			handle_func_t( noQualifiers, false ),
-			finally_func_t( noQualifiers, false )
+			try_func_t( new FunctionType(noQualifiers, false) ),
+			catch_func_t( new FunctionType(noQualifiers, false) ),
+			match_func_t( new FunctionType(noQualifiers, false) ),
+			handle_func_t( new FunctionType(noQualifiers, false) ),
+			finally_func_t( new FunctionType(noQualifiers, false) )
 		{}
 
@@ -141,5 +141,5 @@
 		assert( except_decl );
 
-		ObjectDecl index_obj(
+		auto index_obj = new ObjectDecl(
 			"__handler_index",
 			Type::StorageClasses(),
@@ -149,5 +149,5 @@
 			/*init*/ NULL
 			);
-		ObjectDecl exception_obj(
+		auto exception_obj = new ObjectDecl(
 			"__exception_inst",
 			Type::StorageClasses(),
@@ -160,5 +160,5 @@
 			/*init*/ NULL
 			);
-		ObjectDecl bool_obj(
+		auto bool_obj = new ObjectDecl(
 			"__ret_bool",
 			Type::StorageClasses(),
@@ -169,5 +169,5 @@
 			std::list<Attribute *>{ new Attribute( "unused" ) }
 			);
-		ObjectDecl voidptr_obj(
+		auto voidptr_obj = new ObjectDecl(
 			"__hook",
 			Type::StorageClasses(),
@@ -184,14 +184,14 @@
 			);
 
-		ObjectDecl * unused_index_obj = index_obj.clone();
+		ObjectDecl * unused_index_obj = index_obj->clone();
 		unused_index_obj->attributes.push_back( new Attribute( "unused" ) );
 
-		catch_func_t.get_parameters().push_back( index_obj.clone() );
-		catch_func_t.get_parameters().push_back( exception_obj.clone() );
-		match_func_t.get_returnVals().push_back( unused_index_obj );
-		match_func_t.get_parameters().push_back( exception_obj.clone() );
-		handle_func_t.get_returnVals().push_back( bool_obj.clone() );
-		handle_func_t.get_parameters().push_back( exception_obj.clone() );
-		finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
+		catch_func_t->get_parameters().push_back( index_obj );
+		catch_func_t->get_parameters().push_back( exception_obj->clone() );
+		match_func_t->get_returnVals().push_back( unused_index_obj );
+		match_func_t->get_parameters().push_back( exception_obj->clone() );
+		handle_func_t->get_returnVals().push_back( bool_obj );
+		handle_func_t->get_parameters().push_back( exception_obj );
+		finally_func_t->get_parameters().push_back( voidptr_obj );
 	}
 
@@ -204,5 +204,4 @@
 		call->get_args().push_back( throwStmt->get_expr() );
 		throwStmt->set_expr( nullptr );
-		delete throwStmt;
 		return new ExprStmt( call );
 	}
@@ -234,5 +233,4 @@
 			new UntypedExpr( new NameExpr( "__cfaabi_ehm__rethrow_terminate" ) )
 			) );
-		delete throwStmt;
 		return result;
 	}
@@ -251,5 +249,4 @@
 			);
 		result->labels = throwStmt->labels;
-		delete throwStmt;
 		return result;
 	}
@@ -267,5 +264,5 @@
 
 		return new FunctionDecl( "try", Type::StorageClasses(),
-			LinkageSpec::Cforall, try_func_t.clone(), body );
+			LinkageSpec::Cforall, try_func_t->clone(), body );
 	}
 
@@ -274,5 +271,5 @@
 		std::list<CaseStmt *> handler_wrappers;
 
-		FunctionType *func_type = catch_func_t.clone();
+		FunctionType *func_type = catch_func_t->clone();
 		DeclarationWithType * index_obj = func_type->get_parameters().front();
 		DeclarationWithType * except_obj = func_type->get_parameters().back();
@@ -384,5 +381,4 @@
 		modded_handler->set_cond( nullptr );
 		modded_handler->set_body( nullptr );
-		delete modded_handler;
 		return block;
 	}
@@ -396,5 +392,5 @@
 		CompoundStmt * body = new CompoundStmt();
 
-		FunctionType * func_type = match_func_t.clone();
+		FunctionType * func_type = match_func_t->clone();
 		DeclarationWithType * except_obj = func_type->get_parameters().back();
 
@@ -450,5 +446,5 @@
 		CompoundStmt * body = new CompoundStmt();
 
-		FunctionType * func_type = handle_func_t.clone();
+		FunctionType * func_type = handle_func_t->clone();
 		DeclarationWithType * except_obj = func_type->get_parameters().back();
 
@@ -530,9 +526,8 @@
 		CompoundStmt * body = finally->get_block();
 		finally->set_block( nullptr );
-		delete finally;
 		tryStmt->set_finally( nullptr );
 
 		return new FunctionDecl("finally", Type::StorageClasses(),
-			LinkageSpec::Cforall, finally_func_t.clone(), body);
+			LinkageSpec::Cforall, finally_func_t->clone(), body);
 	}
 
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ControlStruct/MLEMutator.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -226,5 +226,4 @@
 
 		// transform break/continue statements into goto to simplify later handling of branches
-		delete branchStmt;
 		return new BranchStmt( exitLabel, BranchStmt::Goto );
 	}
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/Box.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -281,11 +281,12 @@
 	/// Adds parameters for otype layout to a function type
 	void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
-		BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
-
-		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
-			TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
-			std::string paramName = mangleType( &paramType );
-			layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
-			layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
+		auto sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
+
+		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); 
+				param != otypeParams.end(); ++param ) {
+			auto paramType = new TypeInstType( Type::Qualifiers(), (*param)->get_name(), *param );
+			std::string paramName = mangleType( paramType );
+			layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType->clone(), 0 ) );
+			layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType->clone(), 0 ) );
 		}
 	}
@@ -742,5 +743,6 @@
 				Type * newType = param->clone();
 				if ( env ) env->apply( newType );
-				ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
+				ObjectDecl *newObj = ObjectDecl::newObject( 
+					tempNamer.newName(), newType, nullptr );
 				newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
 				stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
@@ -862,9 +864,7 @@
 			// do not carry over attributes to real type parameters/return values
 			for ( DeclarationWithType * dwt : realType->parameters ) {
-				deleteAll( dwt->get_type()->attributes );
 				dwt->get_type()->attributes.clear();
 			}
 			for ( DeclarationWithType * dwt : realType->returnVals ) {
-				deleteAll( dwt->get_type()->attributes );
 				dwt->get_type()->attributes.clear();
 			}
@@ -987,5 +987,4 @@
 			} // if
 			appExpr->get_args().clear();
-			delete appExpr;
 			return addAssign;
 		}
@@ -1018,5 +1017,4 @@
 						} // if
 						if ( baseType1 || baseType2 ) {
-							delete ret->get_result();
 							ret->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
@@ -1025,5 +1023,4 @@
 							} // if
 							appExpr->get_args().clear();
-							delete appExpr;
 							return ret;
 						} // if
@@ -1035,5 +1032,4 @@
 							Expression *ret = appExpr->get_args().front();
 							// fix expr type to remove pointer
-							delete ret->get_result();
 							ret->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
@@ -1042,5 +1038,4 @@
 							} // if
 							appExpr->get_args().clear();
-							delete appExpr;
 							return ret;
 						} // if
@@ -1182,5 +1177,4 @@
 						Expression *ret = expr->args.front();
 						expr->args.clear();
-						delete expr;
 						return ret;
 					} // if
@@ -1216,8 +1210,6 @@
 			if ( polytype || needs ) {
 				Expression *ret = addrExpr->arg;
-				delete ret->result;
 				ret->result = addrExpr->result->clone();
 				addrExpr->arg = nullptr;
-				delete addrExpr;
 				return ret;
 			} else {
@@ -1229,5 +1221,4 @@
 			if ( retval && returnStmt->expr ) {
 				assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() );
-				delete returnStmt->expr;
 				returnStmt->expr = nullptr;
 			} // if
@@ -1272,5 +1263,4 @@
 				}
 			}
-//  deleteAll( functions );
 		}
 
@@ -1292,5 +1282,4 @@
 			for ( Declaration * param : functionDecl->type->parameters ) {
 				if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) {
-					delete obj->init;
 					obj->init = nullptr;
 				}
@@ -1340,21 +1329,27 @@
 			std::list< DeclarationWithType *> inferredParams;
 			// size/align/offset parameters may not be used in body, pass along with unused attribute.
-			ObjectDecl newObj( "", Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0,
-			                   { new Attribute( "unused" ) } );
-			ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0,
-			                   new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
-			for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
+			auto newObj = new ObjectDecl(
+				"", Type::StorageClasses(), LinkageSpec::C, 0, 
+				new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0,
+			    { new Attribute( "unused" ) } );
+			auto newPtr = new ObjectDecl(
+				"", Type::StorageClasses(), LinkageSpec::C, 0,
+			    new PointerType( Type::Qualifiers(), 
+					new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
+			for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); 
+					tyParm != funcType->get_forall().end(); ++tyParm ) {
 				ObjectDecl *sizeParm, *alignParm;
 				// add all size and alignment parameters to parameter list
 				if ( (*tyParm)->isComplete() ) {
-					TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
-					std::string parmName = mangleType( &parmType );
-
-					sizeParm = newObj.clone();
+					auto parmType = new TypeInstType( 
+						Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
+					std::string parmName = mangleType( parmType );
+
+					sizeParm = newObj->clone();
 					sizeParm->set_name( sizeofName( parmName ) );
 					last = funcType->get_parameters().insert( last, sizeParm );
 					++last;
 
-					alignParm = newObj.clone();
+					alignParm = newObj->clone();
 					alignParm->set_name( alignofName( parmName ) );
 					last = funcType->get_parameters().insert( last, alignParm );
@@ -1379,10 +1374,10 @@
 
 					ObjectDecl *sizeParm, *alignParm, *offsetParm;
-					sizeParm = newObj.clone();
+					sizeParm = newObj->clone();
 					sizeParm->set_name( sizeofName( typeName ) );
 					last = funcType->get_parameters().insert( last, sizeParm );
 					++last;
 
-					alignParm = newObj.clone();
+					alignParm = newObj->clone();
 					alignParm->set_name( alignofName( typeName ) );
 					last = funcType->get_parameters().insert( last, alignParm );
@@ -1392,5 +1387,5 @@
 						// NOTE zero-length arrays are illegal in C, so empty structs have no offset array
 						if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
-							offsetParm = newPtr.clone();
+							offsetParm = newPtr->clone();
 							offsetParm->set_name( offsetofName( typeName ) );
 							last = funcType->get_parameters().insert( last, offsetParm );
@@ -1443,6 +1438,6 @@
 			if ( Type * base = typeDecl->base ) {
 				// add size/align variables for opaque type declarations
-				TypeInstType inst( Type::Qualifiers(), typeDecl->name, typeDecl );
-				std::string typeName = mangleType( &inst );
+				auto inst = new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl );
+				std::string typeName = mangleType( inst );
 				Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 
@@ -1501,7 +1496,5 @@
 							// polymorphic aggregate members should be converted into monomorphic members.
 							// Using char[size_T] here respects the expected sizing rules of an aggregate type.
-							Type * newType = polyToMonoType( field->type );
-							delete field->type;
-							field->type = newType;
+							field->type = polyToMonoType( field->type );
 						}
 					}
@@ -1526,5 +1519,4 @@
 					stmtsToAddBefore.push_back( new DeclStmt( newBuf ) );
 
-					delete objectDecl->get_init();
 					objectDecl->set_init( new SingleInit( new VariableExpr( newBuf ) ) );
 				}
@@ -1605,6 +1597,4 @@
 			}
 
-			delete memberType;
-			delete memberExpr;
 			return newMemberExpr;
 		}
@@ -1626,5 +1616,4 @@
 						addrExpr->arg = nullptr;
 						std::swap( addrExpr->env, ret->env );
-						delete addrExpr;
 						return ret;
 					}
@@ -1635,5 +1624,6 @@
 
 		ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
-			ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, nullptr, type, init );
+			ObjectDecl *newObj = new ObjectDecl( 
+				name, Type::StorageClasses(), LinkageSpec::C, nullptr, type, init );
 			stmtsToAddBefore.push_back( new DeclStmt( newObj ) );
 			return newObj;
@@ -1768,8 +1758,5 @@
 			
 			Expression * gen = genSizeof( ty );
-			if ( gen ) {
-				delete sizeofExpr;
-				return gen;
-			} else return sizeofExpr;
+			return gen ? gen : sizeofExpr;
 		}
 
@@ -1777,7 +1764,5 @@
 			Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result();
 			if ( findGeneric( ty ) ) {
-				Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
-				delete alignofExpr;
-				return ret;
+				return new NameExpr( alignofName( mangleType( ty ) ) );
 			}
 			return alignofExpr;
@@ -1794,10 +1779,7 @@
 				if ( i == -1 ) return offsetofExpr;
 
-				Expression *offsetInd = makeOffsetIndex( ty, i );
-				delete offsetofExpr;
-				return offsetInd;
+				return makeOffsetIndex( ty, i );
 			} else if ( dynamic_cast< UnionInstType* >( ty ) ) {
 				// all union members are at offset zero
-				delete offsetofExpr;
 				return new ConstantExpr( Constant::from_ulong( 0 ) );
 			} else return offsetofExpr;
@@ -1839,5 +1821,4 @@
 			}
 
-			delete offsetPackExpr;
 			return ret;
 		}
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/GenPoly.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -445,5 +445,4 @@
 		Type * newType = arg->clone();
 		if ( env ) env->apply( newType );
-		std::unique_ptr<Type> manager( newType );
 		// if the argument's type is polymorphic, we don't need to box again!
 		return ! isPolyType( newType );
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/InstantiateGeneric.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -58,6 +58,4 @@
 
 		TypeList& operator= ( const TypeList &that ) {
-			deleteAll( params );
-
 			params.clear();
 			cloneAll( that.params, params );
@@ -67,6 +65,4 @@
 
 		TypeList& operator= ( TypeList &&that ) {
-			deleteAll( params );
-
 			params = std::move( that.params );
 
@@ -74,5 +70,5 @@
 		}
 
-		~TypeList() { deleteAll( params ); }
+		~TypeList() {}
 
 		bool operator== ( const TypeList& that ) const {
@@ -293,5 +289,4 @@
 	/// Strips the instances's type parameters
 	void stripInstParams( ReferenceToType *inst ) {
-		deleteAll( inst->get_parameters() );
 		inst->get_parameters().clear();
 	}
@@ -300,6 +295,4 @@
 		substituteMembers( base->get_members(), baseParams, typeSubs );
 
-		// xxx - can't delete type parameters because they may have assertions that are used
-		// deleteAll( baseParams );
 		baseParams.clear();
 
@@ -380,5 +373,4 @@
 			newInst->set_baseStruct( concDecl );
 
-			delete inst;
 			inst = newInst;
 			break;
@@ -390,5 +382,4 @@
 		}
 
-		deleteAll( typeSubs );
 		return inst;
 	}
@@ -430,5 +421,4 @@
 			newInst->set_baseUnion( concDecl );
 
-			delete inst;
 			inst = newInst;
 			break;
@@ -439,5 +429,4 @@
 		}
 
-		deleteAll( typeSubs );
 		return inst;
 	}
@@ -477,5 +466,4 @@
 			ResolvExpr::adjustExprType( ret->result ); // pointer decay
 			std::swap( ret->env, memberExpr->env );
-			delete memberExpr;
 			return ret;
 		}
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/Lvalue.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -51,5 +51,4 @@
 				assertf( base, "expected pointer type in dereference (type was %s)", toString( arg->result ).c_str() );
 				ApplicationExpr * ret = new ApplicationExpr( deref, { arg } );
-				delete ret->result;
 				ret->result = base->clone();
 				ret->result->set_lvalue( true );
@@ -176,5 +175,4 @@
 					return ret;
 				}
-				delete result;
 			}
 			return appExpr;
@@ -235,7 +233,5 @@
 							Type * baseType = InitTweak::getPointerBase( arg->result );
 							assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->result ).c_str() );
-							PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() );
-							delete arg->result;
-							arg->result = ptrType;
+							arg->set_result( new PointerType( Type::Qualifiers(), baseType->clone() ) );
 							arg = mkDeref( arg );
 							// assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
@@ -409,10 +405,8 @@
 				}
 				ret->env = castExpr->env;
-				delete ret->result;
 				ret->result = castExpr->result;
 				castExpr->env = nullptr;
 				castExpr->arg = nullptr;
 				castExpr->result = nullptr;
-				delete castExpr;
 				return ret;
 			} else if ( diff < 0 ) {
@@ -430,5 +424,4 @@
 				}
 				ret->env = castExpr->env;
-				delete ret->result;
 				ret->result = castExpr->result;
 				ret->result->set_lvalue( true ); // ensure result is lvalue
@@ -436,5 +429,4 @@
 				castExpr->arg = nullptr;
 				castExpr->result = nullptr;
-				delete castExpr;
 				return ret;
 			} else {
@@ -451,5 +443,4 @@
 					castExpr->arg = nullptr;
 					std::swap( castExpr->env, ret->env );
-					delete castExpr;
 					return ret;
 				}
@@ -462,5 +453,4 @@
 			Type::Qualifiers qualifiers = refType->get_qualifiers();
 			refType->base = nullptr;
-			delete refType;
 			return new PointerType( qualifiers, base );
 		}
@@ -474,5 +464,4 @@
 				ret->env = expr->env;
 				expr->env = nullptr;
-				delete expr;
 				return ret;
 			} else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( arg ) ) {
@@ -483,5 +472,4 @@
 				ret->env = expr->env;
 				expr->env = nullptr;
-				delete expr;
 
 				// conditional expr type may not be either of the argument types, need to unify
@@ -516,5 +504,4 @@
 					arg0 = nullptr;
 					addrExpr->env = nullptr;
-					delete addrExpr;
 					return ret;
 				}
@@ -546,5 +533,4 @@
 						addrExpr->arg = nullptr;
 						appExpr->env = nullptr;
-						delete appExpr;
 						return ret;
 					}
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/ScrubTyVars.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -28,10 +28,7 @@
 		if ( ! tyVars ) {
 			if ( typeInst->get_isFtype() ) {
-				delete typeInst;
-				return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
+				return new PointerType{ Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) };
 			} else {
-				PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
-				delete typeInst;
-				return ret;
+				return new PointerType{ Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) };
 			}
 		}
@@ -42,12 +39,7 @@
 			  case TypeDecl::Dtype:
 			  case TypeDecl::Ttype:
-				{
-					PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
-					delete typeInst;
-					return ret;
-				}
+				return new PointerType{ Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) };
 			  case TypeDecl::Ftype:
-				delete typeInst;
-				return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
+				return new PointerType{ Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) };
 			} // switch
 		} // if
@@ -57,7 +49,5 @@
 	Type * ScrubTyVars::mutateAggregateType( Type * ty ) {
 		if ( shouldScrub( ty ) ) {
-			PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) );
-			delete ty;
-			return ret;
+			return new PointerType{ Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) };
 		}
 		return ty;
@@ -104,6 +94,4 @@
 			Type * ret = dynType->acceptMutator( *visitor );
 			ret->get_qualifiers() |= pointer->get_qualifiers();
-			pointer->base = nullptr;
-			delete pointer;
 			return ret;
 		}
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/GenPoly/Specialize.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -17,5 +17,4 @@
 #include <iterator>                      // for back_insert_iterator, back_i...
 #include <map>                           // for _Rb_tree_iterator, _Rb_tree_...
-#include <memory>                        // for unique_ptr
 #include <string>                        // for string
 #include <tuple>                         // for get
@@ -193,5 +192,4 @@
 				explodeSimple( new TupleIndexExpr( expr->clone(), i ), out );
 			}
-			delete expr;
 		} else {
 			// non-tuple type - output a clone of the expression
@@ -226,5 +224,4 @@
 			env->apply( actualType );
 		}
-		std::unique_ptr< FunctionType > actualTypeManager( actualType ); // for RAII
 		std::list< DeclarationWithType * >::iterator actualBegin = actualType->get_parameters().begin();
 		std::list< DeclarationWithType * >::iterator actualEnd = actualType->get_parameters().end();
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/InitTweak/FixGlobalInit.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -57,13 +57,9 @@
 		GlobalFixer & fixer = visitor.pass;
 		// don't need to include function if it's empty
-		if ( fixer.initFunction->get_statements()->get_kids().empty() ) {
-			delete fixer.initFunction;
-		} else {
+		if ( ! fixer.initFunction->get_statements()->get_kids().empty() ) {
 			translationUnit.push_back( fixer.initFunction );
 		} // if
 
-		if ( fixer.destroyFunction->get_statements()->get_kids().empty() ) {
-			delete fixer.destroyFunction;
-		} else {
+		if ( ! fixer.destroyFunction->get_statements()->get_kids().empty() ) {
 			translationUnit.push_back( fixer.destroyFunction );
 		} // if
@@ -130,5 +126,4 @@
 				objDecl->set_init( NULL );
 			} // if
-			delete ctorInit;
 		} // if
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/InitTweak/FixInit.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -454,5 +454,4 @@
 				resolved->env = nullptr;
 			} // if
-			delete stmt;
 			if ( TupleAssignExpr * assign = dynamic_cast< TupleAssignExpr * >( resolved ) ) {
 				// fix newly generated StmtExpr
@@ -554,8 +553,5 @@
 				result = result->clone();
 				env->apply( result );
-				if ( ! InitTweak::isConstructable( result ) ) {
-					delete result;
-					return;
-				}
+				if ( ! InitTweak::isConstructable( result ) ) return;
 
 				// create variable that will hold the result of the stmt expr
@@ -652,5 +648,4 @@
 			std::swap( impCpCtorExpr->env, callExpr->env );
 			assert( impCpCtorExpr->env == nullptr );
-			delete impCpCtorExpr;
 
 			if ( returnDecl ) {
@@ -711,7 +706,5 @@
 			if ( unqMap.count( unqExpr->get_id() ) ) {
 				// take data from other UniqueExpr to ensure consistency
-				delete unqExpr->get_expr();
 				unqExpr->set_expr( unqMap[unqExpr->get_id()]->get_expr()->clone() );
-				delete unqExpr->get_result();
 				unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
 				if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
@@ -824,7 +817,8 @@
 							// create a new object which is never used
 							static UniqueName dummyNamer( "_dummy" );
-							ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } );
-							delete ctorInit;
-							return dummy;
+							return new ObjectDecl{
+								dummyNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, 
+								new PointerType{ Type::Qualifiers(), new VoidType( Type::Qualifiers() ) }, 
+								0, std::list< Attribute * >{ new Attribute("unused") } };
 						}
 					} else {
@@ -852,5 +846,4 @@
 					objDecl->init = nullptr;
 				} // if
-				delete ctorInit;
 			} // if
 			return objDecl;
@@ -1228,5 +1221,4 @@
 			ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), callExpr->args.front()->result->clone(), nullptr );
 			declsToAddBefore.push_back( tmp );
-			delete ctorExpr;
 
 			// build assignment and replace constructor's first argument with new temporary
@@ -1237,5 +1229,4 @@
 			// resolve assignment and dispose of new env
 			ResolvExpr::findVoidExpression( assign, indexer );
-			delete assign->env;
 			assign->env = nullptr;
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/InitTweak/GenInit.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -258,6 +258,6 @@
 					// generic parameters should not play a role in determining whether a generic type is constructed - construct all generic types, so that
 					// polymorphic constructors make generic types managed types
-					StructInstType inst( Type::Qualifiers(), aggregateDecl );
-					managedTypes.insert( SymTab::Mangler::mangleConcrete( &inst ) );
+					auto inst = new StructInstType( Type::Qualifiers(), aggregateDecl );
+					managedTypes.insert( SymTab::Mangler::mangleConcrete( inst ) );
 					break;
 				}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/InitTweak/InitTweak.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -5,4 +5,5 @@
 #include <memory>                  // for __shared_ptr
 
+#include "Common/GC.h"             // for new_static_root
 #include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
@@ -122,5 +123,5 @@
 	public:
 		ExprImpl( Expression * expr ) : arg( expr ) {}
-		virtual ~ExprImpl() { delete arg; }
+		virtual ~ExprImpl() = default;
 
 		virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
@@ -166,5 +167,4 @@
 
 	void InitExpander::clearArrayIndices() {
-		deleteAll( indices );
 		indices.clear();
 	}
@@ -263,5 +263,4 @@
 		build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
 		if ( block->get_kids().empty() ) {
-			delete block;
 			return nullptr;
 		} else {
@@ -525,5 +524,7 @@
 			// This operator could easily exist as a real function, but it's tricky because nothing should resolve to this function.
 			TypeDecl * td = new TypeDecl( "T", noStorageClasses, nullptr, TypeDecl::Dtype, true );
-			assign = new FunctionDecl( "?=?", noStorageClasses, LinkageSpec::Intrinsic, SymTab::genAssignType( new TypeInstType( noQualifiers, td->name, td ) ), nullptr );
+			assign = new_static_root<FunctionDecl>( 
+				"?=?", noStorageClasses, LinkageSpec::Intrinsic, 
+				SymTab::genAssignType( new TypeInstType( noQualifiers, td->name, td ) ), nullptr );
 		}
 		if ( dynamic_cast< ReferenceType * >( dst->result ) ) {
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/MakeLibCfa.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -65,10 +65,8 @@
 		struct ZeroOneReplacer {
 			ZeroOneReplacer( Type * t ) : type( t ) {}
-			~ZeroOneReplacer() { delete type; }
 			Type * type = nullptr;
 
 			Type * common( Type * t ) {
 				if ( ! type ) return t;
-				delete t;
 				return type->clone();
 			}
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Makefile.in	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -163,4 +163,5 @@
 	Common/driver_cfa_cpp-UniqueName.$(OBJEXT) \
 	Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT) \
+	Common/driver_cfa_cpp-GC.$(OBJEXT) \
 	Common/driver_cfa_cpp-Assert.$(OBJEXT) \
 	Common/driver_cfa_cpp-Heap.$(OBJEXT) \
@@ -250,4 +251,5 @@
 	SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
+	SynTree/driver_cfa_cpp-BaseSyntaxNode.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT) \
 	Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
@@ -486,8 +488,9 @@
 	CodeTools/TrackLoc.cc Concurrency/Keywords.cc \
 	Concurrency/Waitfor.cc Common/SemanticError.cc \
-	Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \
-	Common/Heap.cc ControlStruct/LabelGenerator.cc \
-	ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \
-	ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \
+	Common/UniqueName.cc Common/DebugMalloc.cc Common/GC.cc \
+	Common/Assert.cc Common/Heap.cc \
+	ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
+	ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
+	ControlStruct/ForExprMutator.cc \
 	ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
 	GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
@@ -527,7 +530,8 @@
 	SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
 	SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
-	SynTree/Attribute.cc SynTree/DeclReplacer.cc \
-	Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
-	Tuples/Explode.cc Virtual/ExpandCasts.cc
+	SynTree/Attribute.cc SynTree/BaseSyntaxNode.cc \
+	SynTree/DeclReplacer.cc Tuples/TupleAssignment.cc \
+	Tuples/TupleExpansion.cc Tuples/Explode.cc \
+	Virtual/ExpandCasts.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -671,4 +675,6 @@
 	Common/$(DEPDIR)/$(am__dirstamp)
 Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \
+	Common/$(DEPDIR)/$(am__dirstamp)
+Common/driver_cfa_cpp-GC.$(OBJEXT): Common/$(am__dirstamp) \
 	Common/$(DEPDIR)/$(am__dirstamp)
 Common/driver_cfa_cpp-Assert.$(OBJEXT): Common/$(am__dirstamp) \
@@ -915,4 +921,6 @@
 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
 	SynTree/$(DEPDIR)/$(am__dirstamp)
+SynTree/driver_cfa_cpp-BaseSyntaxNode.$(OBJEXT):  \
+	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
 SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -976,4 +984,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-GC.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@
@@ -1039,4 +1048,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po@am__quote@
@@ -1298,4 +1308,18 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-DebugMalloc.obj `if test -f 'Common/DebugMalloc.cc'; then $(CYGPATH_W) 'Common/DebugMalloc.cc'; else $(CYGPATH_W) '$(srcdir)/Common/DebugMalloc.cc'; fi`
 
+Common/driver_cfa_cpp-GC.o: Common/GC.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-GC.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-GC.Tpo -c -o Common/driver_cfa_cpp-GC.o `test -f 'Common/GC.cc' || echo '$(srcdir)/'`Common/GC.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-GC.Tpo Common/$(DEPDIR)/driver_cfa_cpp-GC.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Common/GC.cc' object='Common/driver_cfa_cpp-GC.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-GC.o `test -f 'Common/GC.cc' || echo '$(srcdir)/'`Common/GC.cc
+
+Common/driver_cfa_cpp-GC.obj: Common/GC.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-GC.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-GC.Tpo -c -o Common/driver_cfa_cpp-GC.obj `if test -f 'Common/GC.cc'; then $(CYGPATH_W) 'Common/GC.cc'; else $(CYGPATH_W) '$(srcdir)/Common/GC.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-GC.Tpo Common/$(DEPDIR)/driver_cfa_cpp-GC.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Common/GC.cc' object='Common/driver_cfa_cpp-GC.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-GC.obj `if test -f 'Common/GC.cc'; then $(CYGPATH_W) 'Common/GC.cc'; else $(CYGPATH_W) '$(srcdir)/Common/GC.cc'; fi`
+
 Common/driver_cfa_cpp-Assert.o: Common/Assert.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Assert.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo -c -o Common/driver_cfa_cpp-Assert.o `test -f 'Common/Assert.cc' || echo '$(srcdir)/'`Common/Assert.cc
@@ -2515,4 +2539,18 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
+
+SynTree/driver_cfa_cpp-BaseSyntaxNode.o: SynTree/BaseSyntaxNode.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BaseSyntaxNode.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Tpo -c -o SynTree/driver_cfa_cpp-BaseSyntaxNode.o `test -f 'SynTree/BaseSyntaxNode.cc' || echo '$(srcdir)/'`SynTree/BaseSyntaxNode.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/BaseSyntaxNode.cc' object='SynTree/driver_cfa_cpp-BaseSyntaxNode.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BaseSyntaxNode.o `test -f 'SynTree/BaseSyntaxNode.cc' || echo '$(srcdir)/'`SynTree/BaseSyntaxNode.cc
+
+SynTree/driver_cfa_cpp-BaseSyntaxNode.obj: SynTree/BaseSyntaxNode.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BaseSyntaxNode.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Tpo -c -o SynTree/driver_cfa_cpp-BaseSyntaxNode.obj `if test -f 'SynTree/BaseSyntaxNode.cc'; then $(CYGPATH_W) 'SynTree/BaseSyntaxNode.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BaseSyntaxNode.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BaseSyntaxNode.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/BaseSyntaxNode.cc' object='SynTree/driver_cfa_cpp-BaseSyntaxNode.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BaseSyntaxNode.obj `if test -f 'SynTree/BaseSyntaxNode.cc'; then $(CYGPATH_W) 'SynTree/BaseSyntaxNode.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BaseSyntaxNode.cc'; fi`
 
 SynTree/driver_cfa_cpp-DeclReplacer.o: SynTree/DeclReplacer.cc
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Parser/DeclarationNode.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -94,5 +94,4 @@
 
 	delete assert.condition;
-	delete assert.message;
 }
 
@@ -1004,5 +1003,4 @@
 					obj->location = cur->location;
 					* out++ = obj;
-					delete agg;
 				} else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
 					UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Parser/ExpressionNode.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -407,5 +407,4 @@
 	Type * targetType = maybeMoveBuildType( decl_node );
 	if ( dynamic_cast< VoidType * >( targetType ) ) {
-		delete targetType;
 		return new CastExpr( maybeMoveBuild< Expression >(expr_node), false );
 	} else {
@@ -435,7 +434,5 @@
 
 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
-	Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
-	delete member;
-	return ret;
+	return new UntypedOffsetofExpr{ maybeMoveBuildType( decl_node ), member->get_name() };
 } // build_offsetOf
 
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Parser/ParseNode.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -124,15 +124,15 @@
 
 	virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
-		os << expr.get() << std::endl;
+		os << expr << std::endl;
 	}
 	void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
 
 	template<typename T>
-	bool isExpressionType() const {	return nullptr != dynamic_cast<T>(expr.get()); }
-
-	Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
+	bool isExpressionType() const {	return nullptr != dynamic_cast<T>(expr); }
+
+	Expression * build() const { return expr; }
   private:
 	bool extension = false;
-	std::unique_ptr<Expression> expr;
+	Expression* expr;
 }; // ExpressionNode
 
@@ -360,5 +360,5 @@
 
 	virtual StatementNode * clone() const final { assert( false ); return nullptr; }
-	Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
+	Statement * build() const { return stmt; }
 
 	virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
@@ -372,8 +372,8 @@
 
 	virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
-		os << stmt.get() << std::endl;
+		os << stmt << std::endl;
 	}
   private:
-	std::unique_ptr<Statement> stmt;
+	Statement* stmt;
 }; // StatementNode
 
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Parser/StatementNode.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -50,5 +50,5 @@
 		agg = decl;
 	} // if
-	stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) );
+	stmt = new DeclStmt{ maybeMoveBuild< Declaration >(agg) };
 } // StatementNode::StatementNode
 
@@ -58,5 +58,5 @@
 	for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
 		StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
-		assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
+		assert( dynamic_cast< CaseStmt * >(node->stmt) );
 		prev = curr;
 	} // for
@@ -66,5 +66,5 @@
 	buildMoveList( stmt, stmts );
 	// splice any new Statements to end of current Statements
-	CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get());
+	CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt);
 	caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
 	return this;
Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/AdjustExprType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -66,12 +66,9 @@
 
 	Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
-		PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base );
-		arrayType->base = nullptr;
-		delete arrayType;
-		return pointerType;
+		return new PointerType{ arrayType->get_qualifiers(), arrayType->base };
 	}
 
 	Type * AdjustExprType::postmutate( FunctionType * functionType ) {
-		return new PointerType( Type::Qualifiers(), functionType );
+		return new PointerType{ Type::Qualifiers(), functionType };
 	}
 
@@ -80,12 +77,10 @@
 		if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
 			if ( eqvClass.data.kind == TypeDecl::Ftype ) {
-				PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
-				return pointerType;
+				return new PointerType{ Type::Qualifiers(), typeInst };
 			}
 		} else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
 			if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
 				if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
-					PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
-					return pointerType;
+					return new PointerType{ Type::Qualifiers(), typeInst };
 				} // if
 			} // if
Index: src/ResolvExpr/Alternative.cc
===================================================================
--- src/ResolvExpr/Alternative.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/Alternative.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -20,8 +20,11 @@
 #include <utility>                       // for move
 
+#include "Common/GC.h"
+#include "Common/PassVisitor.h"
 #include "Common/utility.h"              // for maybeClone
 #include "ResolvExpr/Cost.h"             // for Cost, Cost::zero, operator<<
 #include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
 #include "SynTree/Expression.h"          // for Expression
+#include "SynTree/GcTracer.h"
 #include "SynTree/Type.h"                // for Type
 
@@ -34,35 +37,15 @@
 	Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
 		: cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {}
-
-	Alternative::Alternative( const Alternative &other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), env( other.env ) {
-	}
-
-	Alternative &Alternative::operator=( const Alternative &other ) {
-		if ( &other == this ) return *this;
-		delete expr;
-		cost = other.cost;
-		cvtCost = other.cvtCost;
-		expr = maybeClone( other.expr );
-		env = other.env;
+	
+	Alternative::Alternative( const Alternative& o )
+		: cost( o.cost ), cvtCost( o.cvtCost ), expr( maybeClone( o.expr ) ), env( o.env ) {}
+	
+	Alternative & Alternative::operator= ( const Alternative& o ) {
+		if ( &o == this ) return *this;
+		cost = o.cost;
+		cvtCost = o.cvtCost;
+		expr = maybeClone( o.expr );
+		env = o.env;
 		return *this;
-	}
-
-	Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( other.env ) {
-		other.expr = nullptr;
-	}
-
-	Alternative & Alternative::operator=( Alternative && other ) {
-		if ( &other == this )  return *this;
-		delete expr;
-		cost = other.cost;
-		cvtCost = other.cvtCost;
-		expr = other.expr;
-		env = other.env;
-		other.expr = nullptr;
-		return *this;
-	}
-
-	Alternative::~Alternative() {
-		delete expr;
 	}
 
@@ -96,4 +79,11 @@
 	}
 
+	const GC& operator<< ( const GC& gc, const Alternative& alt ) {
+		PassVisitor<GcTracer> tracer{ gc };
+		maybeAccept( alt.expr, tracer );
+		tracer << alt.env;
+		return gc;
+	}
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Alternative.h
===================================================================
--- src/ResolvExpr/Alternative.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/Alternative.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -24,4 +24,6 @@
 class Expression;
 
+class GC;
+
 namespace ResolvExpr {
 	struct Alternative {
@@ -30,21 +32,13 @@
 		Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost, const Cost &cvtCost );
 		Alternative( const Alternative &other );
-		Alternative &operator=( const Alternative &other );
-		Alternative( Alternative && other );
-		Alternative &operator=( Alternative && other );
-		~Alternative();
+		Alternative & operator= ( const Alternative &other );
+		Alternative( Alternative&& other ) = default;
+		Alternative & operator= ( Alternative&& other ) = default;
 
 		void print( std::ostream &os, Indenter indent = {} ) const;
 
-		/// Returns the stored expression, but released from management of this Alternative
-		Expression* release_expr() {
-			Expression* tmp = expr;
-			expr = nullptr;
-			return tmp;
-		}
-
 		Cost cost;
 		Cost cvtCost;
-		Expression *expr;
+		Expression * expr;
 		TypeEnvironment env;
 	};
@@ -62,4 +56,6 @@
 		return os;
 	}
+
+	const GC& operator<< ( const GC&, const Alternative& );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -21,5 +21,5 @@
 #include <list>                    // for _List_iterator, list, _List_const_...
 #include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
-#include <memory>                  // for allocator_traits<>::value_type, unique_ptr
+#include <memory>                  // for allocator_traits<>::value_type
 #include <utility>                 // for pair
 #include <vector>                  // for vector
@@ -35,4 +35,5 @@
 #include "ResolveTypeof.h"         // for resolveTypeof
 #include "Resolver.h"              // for resolveStmtExpr
+#include "Common/GC.h"             // for new_static_root
 #include "SymTab/Indexer.h"        // for Indexer
 #include "SymTab/Mangler.h"        // for Mangler
@@ -101,5 +102,5 @@
 		void addAnonConversions( const Alternative & alt );
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
 		/// Adds alternatives for member expressions where the left side has tuple type
 		void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
@@ -165,5 +166,4 @@
 					candidate->env.apply( newType );
 					mangleName = SymTab::Mangler::mangle( newType );
-					delete newType;
 				}
 				std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
@@ -297,27 +297,21 @@
 		// adds anonymous member interpretations whenever an aggregate value type is seen.
 		// it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
-		std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
+		Expression* aggrExpr = alt.expr->clone();
 		alt.env.apply( aggrExpr->get_result() );
 		Type * aggrType = aggrExpr->get_result();
 		if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
 			aggrType = aggrType->stripReferences();
-			aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
+			aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() };
 		}
 
 		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
 		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
 		} // if
 	}
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
-		// by this point, member must be a name expr
-		NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
-		if ( ! nameExpr ) return;
-		const std::string & name = nameExpr->get_name();
+	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
@@ -568,5 +562,4 @@
 
 				Expression *varExpr = data.combine( newerAlt.cvtCost );
-				delete varExpr->get_result();
 				varExpr->set_result( adjType->clone() );
 				PRINT(
@@ -585,6 +578,4 @@
 				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
 				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
-			} else {
-				delete adjType;
 			}
 		}
@@ -634,5 +625,5 @@
 	struct ArgPack {
 		std::size_t parent;                ///< Index of parent pack
-		std::unique_ptr<Expression> expr;  ///< The argument stored here
+		Expression* expr;                  ///< The argument stored here
 		Cost cost;                         ///< The cost of this argument
 		TypeEnvironment env;               ///< Environment for this pack
@@ -681,5 +672,5 @@
 			std::list<Expression*> exprs;
 			const ArgPack* pack = this;
-			if ( expr ) { exprs.push_front( expr.release() ); }
+			if ( expr ) { exprs.push_front( expr ); }
 			while ( pack->tupleStart == 0 ) {
 				pack = &packs[pack->parent];
@@ -688,5 +679,5 @@
 			}
 			// reset pack to appropriate tuple
-			expr.reset( new TupleExpr( exprs ) );
+			expr = new TupleExpr{ exprs };
 			tupleStart = pack->tupleStart - 1;
 			parent = pack->parent;
@@ -741,5 +732,5 @@
 
 						results.emplace_back(
-							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
+							i, expl.exprs[results[i].nextExpl], copy(results[i].env),
 							copy(results[i].need), copy(results[i].have),
 							copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
@@ -762,5 +753,5 @@
 							newResult.parent = i;
 							std::list<Expression*> emptyList;
-							newResult.expr.reset( new TupleExpr( emptyList ) );
+							newResult.expr = new TupleExpr{ emptyList };
 							argType = newResult.expr->get_result();
 						} else {
@@ -769,5 +760,5 @@
 							newResult.cost = results[i].cost;
 							newResult.tupleStart = results[i].tupleStart;
-							newResult.expr.reset( results[i].expr->clone() );
+							newResult.expr = results[i].expr->clone();
 							argType = newResult.expr->get_result();
 
@@ -819,5 +810,5 @@
 						// add new result
 						results.emplace_back(
-							i, expl.exprs.front().get(), move(env), copy(results[i].need),
+							i, expl.exprs.front(), move(env), copy(results[i].need),
 							copy(results[i].have), move(openVars), nextArg + 1,
 							nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
@@ -845,5 +836,5 @@
 			if ( results[i].hasExpl() ) {
 				const ExplodedActual& expl = results[i].getExpl( args );
-				Expression* expr = expl.exprs[results[i].nextExpl].get();
+				Expression* expr = expl.exprs[results[i].nextExpl];
 
 				TypeEnvironment env = results[i].env;
@@ -916,5 +907,5 @@
 
 				// consider only first exploded actual
-				Expression* expr = expl.exprs.front().get();
+				Expression* expr = expl.exprs.front();
 				Type* actualType = expr->result->clone();
 
@@ -1019,5 +1010,5 @@
 
 						results.emplace_back(
-							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
+							i, expl.exprs[results[i].nextExpl], copy(results[i].env),
 							copy(results[i].need), copy(results[i].have),
 							copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
@@ -1055,5 +1046,5 @@
 						// add new result
 						results.emplace_back(
-							i, expl.exprs.front().get(), move(env), copy(results[i].need),
+							i, expl.exprs.front(), move(env), copy(results[i].need),
 							copy(results[i].have), move(openVars), nextArg + 1, 0,
 							expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
@@ -1089,8 +1080,8 @@
 
 		// find function operators
-		static NameExpr *opExpr = new NameExpr( "?()" );
+		static auto *opExpr = new_static_root<NameExpr>( "?()" );
 		AlternativeFinder funcOpFinder( indexer, env );
 		// it's ok if there aren't any defined function ops
-		funcOpFinder.maybeFind( opExpr);
+		funcOpFinder.maybeFind( opExpr );
 		PRINT(
 			std::cerr << "known function ops:" << std::endl;
@@ -1121,6 +1112,6 @@
 				)
 				// check if the type is pointer to function
-				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) {
-					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) {
+				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
+					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
 						Alternative newFunc( *func );
 						referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1128,7 +1119,7 @@
 							std::back_inserter( candidates ) );
 					}
-				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
+				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
 					EqvClass eqvClass;
-					if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
+					if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
 							Alternative newFunc( *func );
@@ -1159,7 +1150,7 @@
 					// check if type is a pointer to function
 					if ( PointerType* pointer = dynamic_cast<PointerType*>(
-							funcOp->expr->result->stripReferences() ) ) {
+							funcOp->expr->get_result()->stripReferences() ) ) {
 						if ( FunctionType* function =
-								dynamic_cast<FunctionType*>( pointer->base ) ) {
+								dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
 							Alternative newFunc( *funcOp );
 							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1183,11 +1174,11 @@
 			PRINT(
 				ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr );
-				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
-				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
-				std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl;
+				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
+				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
+				std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
 				std::cerr << "formals are:" << std::endl;
-				printAll( function->parameters, std::cerr, 8 );
+				printAll( function->get_parameters(), std::cerr, 8 );
 				std::cerr << "actuals are:" << std::endl;
-				printAll( appExpr->args, std::cerr, 8 );
+				printAll( appExpr->get_args(), std::cerr, 8 );
 				std::cerr << "bindings are:" << std::endl;
 				withFunc.env.print( std::cerr, 8 );
@@ -1230,5 +1221,5 @@
 	bool isLvalue( Expression *expr ) {
 		// xxx - recurse into tuples?
-		return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
+		return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
 	}
 
@@ -1265,5 +1256,4 @@
 				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) );
 			}
-			delete argExpr;
 			assert( componentExprs.size() > 0 );
 			// produce the tuple of casts
@@ -1346,4 +1336,13 @@
 	}
 
+	namespace {
+		/// Gets name from untyped member expression (member must be NameExpr)
+		const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
+			NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
+			assert( nameExpr );
+			return nameExpr->get_name();
+		}
+	}
+
 	void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
 		AlternativeFinder funcFinder( indexer, env );
@@ -1354,11 +1353,10 @@
 			Expression * aggrExpr = agg->expr->clone();
 			referenceToRvalueConversion( aggrExpr, cost );
-			std::unique_ptr<Expression> guard( aggrExpr );
 
 			// find member of the given type
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
 				addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
@@ -1605,5 +1603,4 @@
 			alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
 		} // for
-		delete newFirstArg;
 	}
 
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/ConversionCost.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -20,4 +20,5 @@
 #include <string>                        // for operator==, string
 
+#include "Common/GC.h"                   // for new_static_root
 #include "ResolvExpr/Cost.h"             // for Cost
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
@@ -351,6 +352,6 @@
 	void ConversionCost::postvisit( EnumInstType * ) {
 		static Type::Qualifiers q;
-		static BasicType integer( q, BasicType::SignedInt );
-		cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
+		static BasicType* integer = new_static_root<BasicType>( q, BasicType::SignedInt );
+		cost = costFunc( integer, dest, indexer, env );  // safe if dest >= int
 		if ( cost < Cost::unsafe ) {
 			cost.incSafe();
Index: src/ResolvExpr/ExplodedActual.h
===================================================================
--- src/ResolvExpr/ExplodedActual.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/ExplodedActual.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -16,5 +16,4 @@
 #pragma once
 
-#include <memory>
 #include <vector>
 
@@ -29,5 +28,5 @@
 		TypeEnvironment env;
 		Cost cost;
-		std::vector< std::unique_ptr<Expression> > exprs;
+		std::vector< Expression* > exprs;
 
 		ExplodedActual() : env(), cost(Cost::zero), exprs() {}
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -70,9 +70,5 @@
 			Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
 			assert( newExpr->result && ! newExpr->result->isVoid() );
-			Type * newType = newExpr->result;
-			newExpr->result = nullptr;
-			delete typeofType;
-			delete newExpr;
-			return newType;
+			return newExpr->result;
 		} // if
 		return typeofType;
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/Resolver.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -22,4 +22,5 @@
 #include "Alternative.h"                 // for Alternative, AltList
 #include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
+#include "Common/GC.h"                   // for new_generation, collect_young
 #include "Common/PassVisitor.h"          // for PassVisitor
 #include "Common/SemanticError.h"        // for SemanticError
@@ -158,5 +159,4 @@
 					castExpr->arg = nullptr;
 					std::swap( expr->env, castExpr->env );
-					delete castExpr;
 				}
 			}
@@ -167,4 +167,7 @@
 		void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {
 			assertf( untyped, "expected a non-null expression." );
+
+			auto guard = new_generation();  // set up GC generation for this top-level expression
+
 			TypeEnvironment env;
 			AlternativeFinder finder( indexer, env );
@@ -207,7 +210,9 @@
 			Alternative & choice = winners.front();
 			if ( findDeletedExpr( choice.expr ) ) {
+				trace( choice.expr );
 				SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
 			}
 			alt = std::move( choice );
+			trace( alt );
 		}
 
@@ -218,5 +223,4 @@
 			findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, adjust, prune, failFast );
 			finishExpr( choice.expr, choice.env, untyped->env );
-			delete untyped;
 			untyped = choice.expr;
 			choice.expr = nullptr;
@@ -241,20 +245,14 @@
 		assertf( expr, "expected a non-null expression." );
 
-		static CastExpr untyped( nullptr ); // cast to void
+		auto untyped = new CastExpr{ expr }; // cast to void
 
 		// set up and resolve expression cast to void
-		untyped.arg = expr;
 		Alternative choice;
-		findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, true );
+		findUnfinishedKindExpression( untyped, choice, indexer, "", standardAlternativeFilter, true );
 		CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr );
 		env = std::move( choice.env );
 
 		// clean up resolved expression
-		Expression * ret = castExpr->arg;
-		castExpr->arg = nullptr;
-
-		// unlink the arg so that it isn't deleted twice at the end of the program
-		untyped.arg = nullptr;
-		return ret;
+		return castExpr->arg;
 	}
 
@@ -264,5 +262,4 @@
 		Expression * newExpr = resolveInVoidContext( untyped, indexer, env );
 		finishExpr( newExpr, env, untyped->env );
-		delete untyped;
 		untyped = newExpr;
 	}
@@ -445,5 +442,4 @@
 				castExpr->arg = nullptr;
 				std::swap( newExpr->env, castExpr->env );
-				delete castExpr;
 			}
 			caseStmt->condition = newExpr;
@@ -745,5 +741,4 @@
 		// and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
 		newExpr->spliceInferParams( initExpr );
-		delete initExpr;
 
 		// get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
@@ -763,5 +758,4 @@
 							ce->set_arg( nullptr );
 							std::swap( ce->env, newExpr->env );
-							delete ce;
 						}
 					}
@@ -814,8 +808,6 @@
 		// could not find valid constructor, or found an intrinsic constructor
 		// fall back on C-style initializer
-		delete ctorInit->get_ctor();
-		ctorInit->set_ctor( NULL );
-		delete ctorInit->get_dtor();
-		ctorInit->set_dtor( NULL );
+		ctorInit->set_ctor( nullptr );
+		ctorInit->set_dtor( nullptr );
 		maybeAccept( ctorInit->get_init(), *visitor );
 	}
@@ -843,5 +835,4 @@
 
 		// found a constructor - can get rid of C-style initializer
-		delete ctorInit->init;
 		ctorInit->init = nullptr;
 
@@ -850,10 +841,8 @@
 		// to clean up generated code.
 		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
-			delete ctorInit->ctor;
 			ctorInit->ctor = nullptr;
 		}
 
 		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
-			delete ctorInit->dtor;
 			ctorInit->dtor = nullptr;
 		}
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -19,5 +19,7 @@
 #include <utility>                     // for pair
 
+#include "Common/PassVisitor.h"        // for PassVisitor<GcTracer>
 #include "Common/utility.h"            // for maybeClone
+#include "SynTree/GcTracer.h"          // for PassVisitor<GcTracer>
 #include "SynTree/Type.h"              // for Type, FunctionType, Type::Fora...
 #include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
@@ -59,11 +61,6 @@
 	EqvClass &EqvClass::operator=( const EqvClass &other ) {
 		if ( this == &other ) return *this;
-		delete type;
 		initialize( other, *this );
 		return *this;
-	}
-
-	EqvClass::~EqvClass() {
-		delete type;
 	}
 
@@ -147,5 +144,4 @@
 ///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
 					sub.add( *theVar, newTypeInst );
-					delete newTypeInst;
 				} // if
 			} // for
@@ -188,7 +184,5 @@
 					if ( secondClass->type ) {
 						if ( newClass.type ) {
-							Type *newType = combineFunc( newClass.type, secondClass->type );
-							delete newClass.type;
-							newClass.type = newType;
+							newClass.type = combineFunc( newClass.type, secondClass->type );
 							newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
 						} else {
@@ -230,4 +224,11 @@
 		return out;
 	}
+
+	PassVisitor<GcTracer> & operator<<( PassVisitor<GcTracer> & gc, const TypeEnvironment & env ) {
+		for ( const EqvClass & c : env ) {
+			maybeAccept( c.type, gc );
+		}
+		return gc;
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/TypeEnvironment.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -26,4 +26,8 @@
 #include "SynTree/Type.h"              // for Type, Type::ForallList
 #include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
+
+template< typename Pass >
+class PassVisitor;
+class GcTracer;
 
 namespace ResolvExpr {
@@ -76,5 +80,4 @@
 		EqvClass( const EqvClass &other );
 		EqvClass &operator=( const EqvClass &other );
-		~EqvClass();
 		void print( std::ostream &os, Indenter indent = {} ) const;
 	};
@@ -126,4 +129,6 @@
 
 	std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env );
+
+	PassVisitor<GcTracer> & operator<<( PassVisitor<GcTracer> & gc, const TypeEnvironment & env );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/Unify.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -17,5 +17,4 @@
 #include <iterator>               // for back_insert_iterator, back_inserter
 #include <map>                    // for _Rb_tree_const_iterator, _Rb_tree_i...
-#include <memory>                 // for unique_ptr
 #include <set>                    // for set
 #include <string>                 // for string, operator==, operator!=, bas...
@@ -99,8 +98,5 @@
 		findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
 
-		bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
-		delete newFirst;
-		delete newSecond;
-		return result;
+		return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 	}
 
@@ -123,8 +119,5 @@
 ///   newSecond->print( std::cerr );
 ///   std::cerr << std::endl;
-		bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
-		delete newFirst;
-		delete newSecond;
-		return result;
+		return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 	}
 
@@ -171,10 +164,9 @@
 				Type *common = 0;
 				// attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
-				std::unique_ptr< Type > newType( curClass.type->clone() );
+				Type* newType = curClass.type->clone();
 				newType->get_qualifiers() = typeInst->get_qualifiers();
-				if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
+				if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
 					if ( common ) {
 						common->get_qualifiers() = Type::Qualifiers();
-						delete curClass.type;
 						curClass.type = common;
 						env.add( curClass );
@@ -239,5 +231,4 @@
 				if ( common ) {
 					common->get_qualifiers() = Type::Qualifiers();
-					delete class1.type;
 					class1.type = common;
 				} // if
@@ -272,6 +263,4 @@
 			env.add( newClass );
 		} // if
-		delete type1;
-		delete type2;
 		return result;
 	}
@@ -282,12 +271,5 @@
 		findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
 		Type *commonType = 0;
-		if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
-			if ( commonType ) {
-				delete commonType;
-			} // if
-			return true;
-		} else {
-			return false;
-		} // if
+		return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
 	}
 
@@ -483,5 +465,5 @@
 
 	template< typename Iterator, typename Func >
-	std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
+	Type* combineTypes( Iterator begin, Iterator end, Func & toType ) {
 		std::list< Type * > types;
 		for ( ; begin != end; ++begin ) {
@@ -489,5 +471,5 @@
 			flatten( toType( *begin ), back_inserter( types ) );
 		}
-		return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
+		return new TupleType{ Type::Qualifiers(), types };
 	}
 
@@ -504,8 +486,8 @@
 			if ( isTtype1 && ! isTtype2 ) {
 				// combine all of the things in list2, then unify
-				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( isTtype2 && ! isTtype1 ) {
 				// combine all of the things in list1, then unify
-				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
 				return false;
@@ -517,5 +499,5 @@
 			Type * t1 = (*list1Begin)->get_type();
 			if ( Tuples::isTtype( t1 ) ) {
-				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else if ( list2Begin != list2End ) {
@@ -523,5 +505,5 @@
 			Type * t2 = (*list2Begin)->get_type();
 			if ( Tuples::isTtype( t2 ) ) {
-				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else {
@@ -544,5 +526,4 @@
 					// expand ttype parameter into its actual type
 					if ( eqvClass.type ) {
-						delete typeInst;
 						return eqvClass.type->clone();
 					}
@@ -569,5 +550,4 @@
 				dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) );
 			}
-			delete dcl;
 		}
 	}
@@ -578,6 +558,6 @@
 			// flatten the parameter lists for both functions so that tuple structure
 			// doesn't affect unification. Must be a clone so that the types don't change.
-			std::unique_ptr<FunctionType> flatFunc( functionType->clone() );
-			std::unique_ptr<FunctionType> flatOther( otherFunction->clone() );
+			FunctionType* flatFunc = functionType->clone();
+			FunctionType* flatOther = otherFunction->clone();
 			flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env );
 			flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env );
@@ -720,8 +700,8 @@
 			if ( isTtype1 && ! isTtype2 ) {
 				// combine all of the things in list2, then unify
-				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( isTtype2 && ! isTtype1 ) {
 				// combine all of the things in list1, then unify
-				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
 				return false;
@@ -733,5 +713,5 @@
 			Type * t1 = *list1Begin;
 			if ( Tuples::isTtype( t1 ) ) {
-				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else if ( list2Begin != list2End ) {
@@ -739,5 +719,5 @@
 			Type * t2 = *list2Begin;
 			if ( Tuples::isTtype( t2 ) ) {
-				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else {
@@ -748,6 +728,6 @@
 	void Unify::postvisit(TupleType *tupleType) {
 		if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
-			std::unique_ptr<TupleType> flat1( tupleType->clone() );
-			std::unique_ptr<TupleType> flat2( otherTuple->clone() );
+			TupleType* flat1 = tupleType->clone();
+			TupleType* flat2 = otherTuple->clone();
 			std::list<Type *> types1, types2;
 
@@ -756,6 +736,6 @@
 			flat2->acceptMutator( expander );
 
-			flatten( flat1.get(), back_inserter( types1 ) );
-			flatten( flat2.get(), back_inserter( types2 ) );
+			flatten( flat1, back_inserter( types1 ) );
+			flatten( flat2, back_inserter( types2 ) );
 
 			result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, indexer );
Index: src/ResolvExpr/Unify.h
===================================================================
--- src/ResolvExpr/Unify.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/ResolvExpr/Unify.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -64,10 +64,5 @@
 	bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
 		std::list< Type* > commonTypes;
-		if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
-			deleteAll( commonTypes );
-			return true;
-		} else {
-			return false;
-		} // if
+		return unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes );
 	}
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SymTab/Autogen.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -214,5 +214,4 @@
 	void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
 		FunctionDecl * decl = functionDecl->clone();
-		delete decl->statements;
 		decl->statements = nullptr;
 		declsToAdd.push_back( decl );
@@ -333,5 +332,4 @@
 		} catch ( SemanticErrorException & ) {
 			// okay if decl does not resolve - that means the function should not be generated
-			delete dcl;
 		}
 	}
@@ -373,5 +371,4 @@
 			// do not carry over field's attributes to parameter type
 			Type * paramType = field->get_type()->clone();
-			deleteAll( paramType->attributes );
 			paramType->attributes.clear();
 			// add a parameter corresponding to this field
@@ -383,5 +380,4 @@
 			resolve( ctor );
 		}
-		delete memCtorType;
 	}
 
@@ -511,5 +507,4 @@
 			// do not carry over field's attributes to parameter type
 			Type * paramType = field->get_type()->clone();
-			deleteAll( paramType->attributes );
 			paramType->attributes.clear();
 			// add a parameter corresponding to this field
@@ -524,5 +519,4 @@
 			break;
 		}
-		delete memCtorType;
 	}
 
@@ -594,7 +588,7 @@
 		// must visit children (enum constants) to add them to the indexer
 		if ( enumDecl->has_body() ) {
-			EnumInstType enumInst( Type::Qualifiers(), enumDecl->get_name() );
-			enumInst.set_baseEnum( enumDecl );
-			EnumFuncGenerator gen( &enumInst, data, functionNesting, indexer );
+			auto enumInst = new EnumInstType{ Type::Qualifiers(), enumDecl->get_name() };
+			enumInst->set_baseEnum( enumDecl );
+			EnumFuncGenerator gen( enumInst, data, functionNesting, indexer );
 			generateFunctions( gen, declsToAddAfter );
 		}
@@ -604,10 +598,10 @@
 		visit_children = false;
 		if ( structDecl->has_body() ) {
-			StructInstType structInst( Type::Qualifiers(), structDecl->name );
-			structInst.set_baseStruct( structDecl );
+			auto structInst = new StructInstType{ Type::Qualifiers(), structDecl->name };
+			structInst->set_baseStruct( structDecl );
 			for ( TypeDecl * typeDecl : structDecl->parameters ) {
-				structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
-			}
-			StructFuncGenerator gen( structDecl, &structInst, data, functionNesting, indexer );
+				structInst->parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
+			}
+			StructFuncGenerator gen( structDecl, structInst, data, functionNesting, indexer );
 			generateFunctions( gen, declsToAddAfter );
 		} // if
@@ -617,10 +611,10 @@
 		visit_children = false;
 		if ( unionDecl->has_body()  ) {
-			UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
-			unionInst.set_baseUnion( unionDecl );
+			auto unionInst = new UnionInstType{ Type::Qualifiers(), unionDecl->get_name() };
+			unionInst->set_baseUnion( unionDecl );
 			for ( TypeDecl * typeDecl : unionDecl->get_parameters() ) {
-				unionInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
-			}
-			UnionFuncGenerator gen( unionDecl, &unionInst, data, functionNesting, indexer );
+				unionInst->get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
+			}
+			UnionFuncGenerator gen( unionDecl, unionInst, data, functionNesting, indexer );
 			generateFunctions( gen, declsToAddAfter );
 		} // if
@@ -631,6 +625,6 @@
 		if ( ! typeDecl->base ) return;
 
-		TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl );
-		TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer );
+		auto refType = new TypeInstType{ Type::Qualifiers(), typeDecl->name, typeDecl };
+		TypeFuncGenerator gen( typeDecl, refType, data, functionNesting, indexer );
 		generateFunctions( gen, declsToAddAfter );
 
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SymTab/Autogen.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -97,5 +97,4 @@
 		// return if adding reference fails - will happen on default constructor and destructor
 		if ( isReferenceCtorDtor && ! srcParam.addReference() ) {
-			delete fExpr;
 			return listInit;
 		}
Index: src/SymTab/FixFunction.cc
===================================================================
--- src/SymTab/FixFunction.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SymTab/FixFunction.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -28,10 +28,8 @@
 
 	DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) {
-		// can't delete function type because it may contain assertions, so transfer ownership to new object
-		ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );
-		functionDecl->attributes.clear();
-		functionDecl->type = nullptr;
-		delete functionDecl;
-		return pointer;
+		return new ObjectDecl{ 
+			functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, 
+			new PointerType{ Type::Qualifiers(), functionDecl->type }, 
+			nullptr, functionDecl->attributes };
 	}
 
@@ -42,9 +40,5 @@
 	Type * FixFunction::postmutate(ArrayType *arrayType) {
 		// need to recursively mutate the base type in order for multi-dimensional arrays to work.
-		PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
-		arrayType->base = nullptr;
-		arrayType->dimension = nullptr;
-		delete arrayType;
-		return pointerType;
+		return new PointerType{ arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic };
 	}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SymTab/Validate.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -48,4 +48,5 @@
 #include "CodeGen/CodeGenerator.h"     // for genName
 #include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
+#include "Common/GC.h"                 // for new_static_root, register_static_root
 #include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
 #include "Common/ScopedMap.h"          // for ScopedMap
@@ -199,6 +200,5 @@
 		void addImplicitTypedef( AggDecl * aggDecl );
 
-		typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr;
-		typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap;
+		typedef ScopedMap< std::string, std::pair< TypedefDecl*, int > > TypedefMap;
 		typedef std::map< std::string, TypeDecl * > TypeDeclMap;
 		TypedefMap typedefNames;
@@ -312,5 +312,5 @@
 		} // if
 		// Always remove the hoisted aggregate from the inner structure.
-		GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, shouldHoist, false ); } );
+		GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, shouldHoist ); } );
 	}
 
@@ -373,5 +373,4 @@
 			// one void is the only thing in the list; remove it.
 			if ( containsVoid ) {
-				delete dwts.front();
 				dwts.clear();
 			}
@@ -500,5 +499,4 @@
 				}
 			}
-			deleteAll( td->assertions );
 			td->assertions.clear();
 		} // for
@@ -616,5 +614,4 @@
 					// expand trait instance into all of its members
 					expandAssertions( traitInst, back_inserter( type->assertions ) );
-					delete traitInst;
 				} else {
 					// pass other assertions through
@@ -688,10 +685,12 @@
 			// grab and remember declaration of size_t
 			SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
+			GC::get().register_static_root( SizeType );
 		} else {
 			// xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
 			// eventually should have a warning for this case.
-			SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
-		}
-		filter( translationUnit, isTypedef, true );
+			SizeType = 
+				new_static_root<BasicType>( Type::Qualifiers(), BasicType::LongUnsignedInt );
+		}
+		filter( translationUnit, isTypedef );
 	}
 
@@ -707,5 +706,4 @@
 				ret->attributes.splice( ret->attributes.end(), typeInst->attributes );
 			} else {
-				deleteAll( ret->attributes );
 				ret->attributes.clear();
 			}
@@ -720,5 +718,4 @@
 				mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
 			} // if
-			delete typeInst;
 			return ret;
 		} else {
@@ -762,5 +759,5 @@
 			}
 		} else {
-			typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
+			typedefNames[ tyDecl->get_name() ] = std::make_pair( tyDecl, scopeLevel );
 		} // if
 
@@ -806,9 +803,7 @@
 		if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
 			// replace the current object declaration with a function declaration
-			FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
-			objDecl->get_attributes().clear();
-			objDecl->set_type( nullptr );
-			delete objDecl;
-			return newDecl;
+			return new FunctionDecl{ 
+				objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), 
+				funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() };
 		} // if
 		return objDecl;
@@ -834,5 +829,5 @@
 			} // if
 			return false;
-		}, true);
+		} );
 		return compoundStmt;
 	}
@@ -842,5 +837,5 @@
 	template<typename AggDecl>
 	AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
-		filter( aggDecl->members, isTypedef, true );
+		filter( aggDecl->members, isTypedef );
 		return aggDecl;
 	}
@@ -857,6 +852,6 @@
 				type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
 			} // if
-			TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
-			typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
+			TypedefDecl* tyDecl = new TypedefDecl{ aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() };
+			typedefNames[ aggDecl->get_name() ] = std::make_pair( tyDecl, scopeLevel );
 		} // if
 	}
@@ -972,8 +967,6 @@
 		static UniqueName indexName( "_compLit" );
 
-		ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
-		compLitExpr->set_result( nullptr );
-		compLitExpr->set_initializer( nullptr );
-		delete compLitExpr;
+		ObjectDecl * tempvar = new ObjectDecl{ 
+			indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() };
 		declsToAddBefore.push_back( tempvar );					// add modified temporary to current block
 		return new VariableExpr( tempvar );
@@ -1011,5 +1004,4 @@
 			// ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
 			ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
-			deleteAll( retVals );
 			retVals.clear();
 			retVals.push_back( newRet );
@@ -1052,7 +1044,5 @@
 			if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
 				if ( labels.count( nameExpr->name ) ) {
-					Label name = nameExpr->name;
-					delete addrExpr;
-					return new LabelAddressExpr( name );
+					return new LabelAddressExpr{ nameExpr->name };
 				}
 			}
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/AddressExpr.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/AggregateDecl.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/ApplicationExpr.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/ArrayType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/AttrType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Attribute.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Attribute.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 eba74ba03a2c29999def828ffaf6afc87e2b40d1)
+++ src/SynTree/BaseSyntaxNode.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/BaseSyntaxNode.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/CommaExpr.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/CompoundStmt.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Constant.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Constant.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/DeclStmt.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Declaration.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Declaration.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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; }
@@ -372,5 +364,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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/DeclarationWithType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Expression.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Expression.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 ); }
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/FunctionDecl.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/FunctionType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 eba74ba03a2c29999def828ffaf6afc87e2b40d1)
+++ src/SynTree/GcTracer.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Initializer.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Initializer.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/NamedTypeDecl.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/ObjectDecl.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/PointerType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/ReferenceToType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/ReferenceType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Statement.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Statement.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 *>() );
@@ -225,5 +218,4 @@
 	       Statement *body, bool isDoWhile = false );
 	WhileStmt( const WhileStmt &other );
-	virtual ~WhileStmt();
 
 	Expression *get_condition() { return condition; }
@@ -250,5 +242,4 @@
 	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
 	ForStmt( const ForStmt &other );
-	virtual ~ForStmt();
 
 	std::list<Statement *> &get_initialization() { return initialization; }
@@ -303,5 +294,4 @@
 	ReturnStmt( Expression *expr );
 	ReturnStmt( const ReturnStmt &other );
-	virtual ~ReturnStmt();
 
 	Expression *get_expr() { return expr; }
@@ -324,5 +314,4 @@
 	ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
 	ThrowStmt( const ThrowStmt &other );
-	virtual ~ThrowStmt();
 
 	Kind get_kind() { return kind; }
@@ -346,5 +335,4 @@
 	TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
 	TryStmt( const TryStmt &other );
-	virtual ~TryStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -373,5 +361,4 @@
 	           Expression *cond, Statement *body );
 	CatchStmt( const CatchStmt &other );
-	virtual ~CatchStmt();
 
 	Kind get_kind() { return kind; }
@@ -395,5 +382,4 @@
 	FinallyStmt( CompoundStmt *block );
 	FinallyStmt( const FinallyStmt &other );
-	virtual ~FinallyStmt();
 
 	CompoundStmt *get_block() const { return block; }
@@ -422,5 +408,4 @@
 	WaitForStmt();
 	WaitForStmt( const WaitForStmt & );
-	virtual ~WaitForStmt();
 
 	std::vector<Clause> clauses;
@@ -451,5 +436,4 @@
 	WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
 	WithStmt( const WithStmt & other );
-	virtual ~WithStmt();
 
 	virtual WithStmt * clone() const override { return new WithStmt( *this ); }
@@ -467,5 +451,4 @@
 	DeclStmt( Declaration *decl );
 	DeclStmt( const DeclStmt &other );
-	virtual ~DeclStmt();
 
 	Declaration *get_decl() const { return decl; }
@@ -489,5 +472,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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TupleExpr.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TupleType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Type.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Type.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TypeDecl.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TypeExpr.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TypeSubstitution.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TypeSubstitution.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/TypeofType.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -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 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/Visitor.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -124,4 +124,6 @@
 
 	virtual void visit( Attribute * attribute ) = 0;
+
+	virtual void visit( TypeSubstitution * sub ) = 0;
 };
 
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/SynTree/module.mk	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -48,4 +48,5 @@
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
+       SynTree/BaseSyntaxNode.cc \
        SynTree/DeclReplacer.cc
 
Index: src/Tuples/Explode.cc
===================================================================
--- src/Tuples/Explode.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Tuples/Explode.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -70,6 +70,5 @@
 				// should now be a tuple of references rather than a reference to a tuple.
 				// Still, this code is a bit awkward, and could use some improvement.
-				UniqueExpr * newUniqueExpr = new UniqueExpr( applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() );
-				delete uniqueExpr;
+				UniqueExpr * newUniqueExpr = new UniqueExpr{ applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() };
 				if ( castAdded ) {
 					// if a cast was added by applyCast, then unique expr now has one more layer of reference
@@ -88,9 +87,5 @@
 				// field is consistent with the type of the tuple expr, since the field
 				// may have changed from type T to T&.
-				Expression * expr = tupleExpr->get_tuple();
-				tupleExpr->set_tuple( nullptr );
-				TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() );
-				delete tupleExpr;
-				return ret;
+				return new TupleIndexExpr( tupleExpr->get_tuple(), tupleExpr->get_index() );
 			}
 		};
Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Tuples/Explode.h	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -27,5 +27,5 @@
 namespace SymTab {
 class Indexer;
-}  // namespace SymTab
+}  // namespace SymTabf
 
 namespace Tuples {
@@ -67,5 +67,5 @@
 				for ( ResolvExpr::Alternative & alt : alts ) {
 					// distribute reference cast over all components
-					append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
+					append( std::forward<Output>(out), distributeReference( alt.expr ),
 						alt.env, alt.cost, alt.cvtCost );
 				}
@@ -96,7 +96,5 @@
 					TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
 					explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );
-					delete idx;
 				}
-				delete arg;
 			}
 		} else {
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Tuples/TupleExpansion.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -46,10 +46,4 @@
 
 			std::map< int, Expression * > decls; // not vector, because order added may not be increasing order
-
-			~UniqueExprExpander() {
-				for ( std::pair<const int, Expression *> & p : decls ) {
-					delete p.second;
-				}
-			}
 		};
 
@@ -112,7 +106,4 @@
 				UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->member, inner );
 				inner->location = newMemberExpr->location = loc;
-				memberExpr->member = nullptr;
-				memberExpr->aggregate = nullptr;
-				delete memberExpr;
 				return newMemberExpr->acceptMutator( expander );
 			} else {
@@ -134,5 +125,4 @@
 				expr->location = memberExpr->location;
 			}
-			delete aggr;
 			tupleExpr->location = memberExpr->location;
 			return tupleExpr;
@@ -180,5 +170,4 @@
 			decls[id] = condExpr;
 		}
-		delete unqExpr;
 		return decls[id]->clone();
 	}
@@ -190,5 +179,4 @@
 		ret->set_env( assnExpr->get_env() );
 		assnExpr->set_env( nullptr );
-		delete assnExpr;
 		return ret;
 	}
@@ -221,5 +209,4 @@
 			newType->get_parameters().push_back( new TypeExpr( t->clone() ) );
 		}
-		delete tupleType;
 		return newType;
 	}
@@ -242,5 +229,4 @@
 				ret->env = env;
 				expr = nullptr; // remove from list so it can safely be deleted
-				delete tupleExpr;
 				return ret;
 			}
@@ -287,9 +273,8 @@
 		TypeSubstitution * env = tupleExpr->get_env();
 
-		// remove data from shell and delete it
+		// remove data from shell
 		tupleExpr->set_result( nullptr );
 		tupleExpr->get_exprs().clear();
 		tupleExpr->set_env( nullptr );
-		delete tupleExpr;
 
 		return replaceTupleExpr( result, exprs, env );
Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/Virtual/ExpandCasts.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -139,5 +139,5 @@
 		ObjectDecl * table = found->second;
 
-		Expression * result = new CastExpr(
+		return new CastExpr{
 			//new ApplicationExpr(
 				//new AddressExpr( new VariableExpr( vcast_decl ) ),
@@ -158,10 +158,5 @@
 				} ),
 			castExpr->get_result()->clone()
-			);
-
-		castExpr->set_arg( nullptr );
-		castExpr->set_result( nullptr );
-		delete castExpr;
-		return result;
+		};
 	}
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 58e822a10f30dad8a7f188f7c7fb9c07c071994c)
+++ src/main.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -1,2 +1,3 @@
+
 //
 // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
@@ -35,4 +36,5 @@
 #include "CodeTools/TrackLoc.h"             // for fillLocations
 #include "Common/CompilerError.h"           // for CompilerError
+#include "Common/GC.h"                      // for GC
 #include "Common/Heap.h"
 #include "Common/PassVisitor.h"
@@ -57,4 +59,5 @@
 #include "SymTab/Validate.h"                // for validate
 #include "SynTree/Declaration.h"            // for Declaration
+#include "SynTree/GcTracer.h"               // for GC << TranslationUnit
 #include "SynTree/Visitor.h"                // for acceptAll
 #include "Tuples/Tuples.h"                  // for expandMemberTuples, expan...
@@ -177,9 +180,4 @@
 	signal( SIGABRT, sigAbortHandler );
 
-	// std::cout << "main" << std::endl;
-	// for ( int i = 0; i < argc; i += 1 ) {
-	// 	std::cout << '\t' << argv[i] << std::endl;
-	// } // for
-
 	parse_cmdline( argc, argv, filename );				// process command-line arguments
 	CodeGen::FixMain::setReplaceMain( !nomainp );
@@ -240,4 +238,5 @@
 		delete parseTree;
 		parseTree = nullptr;
+		collect( translationUnit );
 
 		if ( astp ) {
@@ -248,8 +247,6 @@
 		// add the assignment statement after the initialization of a type parameter
 		PASS( "validate", SymTab::validate( translationUnit, symtabp ) );
-		if ( symtabp ) {
-			deleteAll( translationUnit );
-			return 0;
-		} // if
+		if ( symtabp ) return 0;
+		collect( translationUnit );
 
 		if ( expraltp ) {
@@ -268,4 +265,5 @@
 		PASS( "genInit", InitTweak::genInit( translationUnit ) );
 		PASS( "expandMemberTuples" , Tuples::expandMemberTuples( translationUnit ) );
+		collect( translationUnit );
 		if ( libcfap ) {
 			// generate the bodies of cfa library functions
@@ -275,5 +273,4 @@
 		if ( declstatsp ) {
 			CodeTools::printDeclStats( translationUnit );
-			deleteAll( translationUnit );
 			return 0;
 		}
@@ -287,4 +284,5 @@
 
 		PASS( "resolve", ResolvExpr::resolve( translationUnit ) );
+		collect( translationUnit );
 		if ( exprp ) {
 			dump( translationUnit );
@@ -294,4 +292,5 @@
 		// fix ObjectDecl - replaces ConstructorInit nodes
 		PASS( "fixInit", InitTweak::fix( translationUnit, filename, libcfap || treep ) );
+		collect( translationUnit );
 		if ( ctorinitp ) {
 			dump ( translationUnit );
@@ -308,5 +307,5 @@
 
 		PASS( "expandTuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
-
+		collect( translationUnit );
 		if ( tuplep ) {
 			dump( translationUnit );
@@ -317,4 +316,5 @@
 
 		PASS( "instantiateGenerics", GenPoly::instantiateGeneric( translationUnit ) );
+		collect( translationUnit );
 		if ( genericsp ) {
 			dump( translationUnit );
@@ -322,6 +322,5 @@
 		}
 		PASS( "convertLvalue", GenPoly::convertLvalue( translationUnit ) );
-
-
+		collect( translationUnit );
 		if ( bboxp ) {
 			dump( translationUnit );
@@ -329,5 +328,5 @@
 		} // if
 		PASS( "box", GenPoly::box( translationUnit ) );
-
+		collect( translationUnit );
 		if ( bcodegenp ) {
 			dump( translationUnit );
@@ -385,5 +384,4 @@
 	}// try
 
-	deleteAll( translationUnit );
 	if(!libcfap && !treep) HeapStats::printStats();
 	return 0;
@@ -601,5 +599,4 @@
 		printAll( decls, out );
 	}
-	deleteAll( translationUnit );
 } // dump
 
