Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/CodeGen/CodeGenerator.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -1106,13 +1106,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/Common/GC.cc
===================================================================
--- src/Common/GC.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/Common/GC.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -16,4 +16,8 @@
 #include "GC.h"
 
+#include "Common/PassVisitor.h"
+
+#include "SynTree/GcTracer.h"
+
 #include <algorithm>
 #include <cassert>
@@ -24,5 +28,5 @@
 }
 
-GC::GC() : mark(false), old(), young(), using_young(false) {
+GC::GC() : mark(false), using_young(false), old(), young(), static_roots() {
 	old.reserve(70000);
 }
@@ -55,6 +59,17 @@
 }
 
+void GC::register_static_root(BaseSyntaxNode* root) {
+	static_roots.push_back(root);
+}
+
 void GC::new_generation() {
 	using_young = true;
+}
+
+void GC::trace_static_roots() {
+	PassVisitor<GcTracer> tracer{ *this };
+	for ( BaseSyntaxNode* root : static_roots ) {
+		root->accept( tracer );
+	}
 }
 
Index: src/Common/GC.h
===================================================================
--- src/Common/GC.h	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/Common/GC.h	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -20,4 +20,5 @@
 class GC_Traceable;
 class GC_Object;
+class BaseSyntaxNode;
 
 /// Manually traced and called garbage collector
@@ -34,6 +35,12 @@
 	void register_object(GC_Object*);
 
+	/// Adds an object to the set of static roots
+	void register_static_root(BaseSyntaxNode*);
+
 	/// Use young generation for subsequent new objects
 	void new_generation();
+
+	/// Traces all static roots
+	void trace_static_roots();
 
 	/// Collects the young generation, placing survivors in old generation.
@@ -50,11 +57,13 @@
 	GC();
 
-	/// The current collection's mark bit
-	bool mark;
+	bool mark;                 ///< The current collection's mark bit
+	bool using_young;          ///< Is the young generation in use?
 
-	typedef std::vector<class GC_Object*> Generation;
-	Generation old;
-	Generation young;
-	bool using_young;
+	using Generation = std::vector<GC_Object*>;
+	Generation old;            ///< Old generation
+	Generation young;          ///< Young generation
+
+	using StaticRoots = std::vector<BaseSyntaxNode*>;
+	StaticRoots static_roots;  ///< Set of static-lifetime roots
 };
 
@@ -80,4 +89,5 @@
 	GC& gc = GC::get();
 	traceAll(gc, roots...);
+	gc.trace_static_roots();
 	gc.collect_young();
 }
@@ -88,5 +98,14 @@
 	GC& gc = GC::get();
 	traceAll(gc, roots...);
+	gc.trace_static_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;
 }
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/Common/PassVisitor.impl.h	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -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 );
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/Concurrency/Keywords.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -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
@@ -203,5 +204,5 @@
 	};
 
-	Type* MutexKeyword::generic_func = new FunctionType{ noQualifiers, true };
+	Type* MutexKeyword::generic_func = new_static_root<FunctionType>( noQualifiers, true );
 
 	//-----------------------------------------------------------------------------
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/Makefile.in	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -250,4 +250,5 @@
 	SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
+	SynTree/driver_cfa_cpp-BaseSyntaxNode.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-VarExprReplacer.$(OBJEXT) \
 	Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
@@ -527,7 +528,8 @@
 	SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
 	SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
-	SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
-	Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
-	Tuples/Explode.cc Virtual/ExpandCasts.cc
+	SynTree/Attribute.cc SynTree/BaseSyntaxNode.cc \
+	SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
+	Tuples/TupleExpansion.cc Tuples/Explode.cc \
+	Virtual/ExpandCasts.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -915,4 +917,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-VarExprReplacer.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -1039,4 +1043,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@
@@ -2515,4 +2520,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-VarExprReplacer.o: SynTree/VarExprReplacer.cc
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/ResolvExpr/Resolver.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -219,20 +219,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;
 	}
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/SymTab/Autogen.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -588,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 );
 		}
@@ -598,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
@@ -611,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
@@ -625,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/SynTree/GcTracer.h
===================================================================
--- src/SynTree/GcTracer.h	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/SynTree/GcTracer.h	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -20,4 +20,5 @@
 #include "BaseSyntaxNode.h"
 #include "Expression.h"
+#include "Type.h"
 
 #include "Common/GC.h"
@@ -47,4 +48,8 @@
 		maybeAccept( expr->env, *visitor );
 	}
+
+	void postvisit( PointerType* pty ) {
+		maybeAccept( pty->dimension, *visitor );
+	}
 };
 
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/SynTree/module.mk	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -48,4 +48,5 @@
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
+       SynTree/BaseSyntaxNode.cc \
        SynTree/VarExprReplacer.cc
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 7e4b44db4aee3e4db9e5c3f78521d2db85fd048b)
+++ src/main.cc	(revision bd06384ff9b3300e1d878bc19523e6051209bb15)
@@ -244,6 +244,6 @@
 		OPTPRINT( "validate" )
 		SymTab::validate( translationUnit, symtabp );
-		collect( translationUnit );
 		if ( symtabp ) return 0;
+		collect( translationUnit );
 
 		if ( expraltp ) {
