Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/Autogen.cc	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -16,5 +16,4 @@
 #include "Autogen.h"
 
-#include <cstddef>                 // for NULL
 #include <algorithm>               // for count_if
 #include <cassert>                 // for strict_dynamic_cast, assert, assertf
@@ -32,4 +31,6 @@
 #include "GenPoly/DeclMutator.h"   // for DeclMutator
 #include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
+#include "InitTweak/GenInit.h"     // for fixReturnStatements
+#include "ResolvExpr/Resolver.h"   // for resolveDecl
 #include "SymTab/Mangler.h"        // for Mangler
 #include "SynTree/Attribute.h"     // For Attribute
@@ -108,5 +109,5 @@
 
 	bool isUnnamedBitfield( ObjectDecl * obj ) {
-		return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
+		return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
 	}
 
@@ -115,5 +116,5 @@
 		FunctionDecl * decl = functionDecl->clone();
 		delete decl->get_statements();
-		decl->set_statements( NULL );
+		decl->set_statements( nullptr );
 		declsToAdd.push_back( decl );
 		decl->fixUniqueId();
@@ -326,5 +327,5 @@
 				assert( ! func->get_functionType()->get_parameters().empty() );
 				ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
-				ObjectDecl * srcParam = NULL;
+				ObjectDecl * srcParam = nullptr;
 				if ( func->get_functionType()->get_parameters().size() == 2 ) {
 					srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
@@ -333,5 +334,5 @@
 				assert( dstParam );
 
-				Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
+				Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
 				makeStructMemberOp( dstParam, srcselect, field, func, forward );
 			} // if
@@ -372,5 +373,5 @@
 				} else {
 					// no matching parameter, initialize field with default ctor
-					makeStructMemberOp( dstParam, NULL, field, func );
+					makeStructMemberOp( dstParam, nullptr, field, func );
 				}
 			}
@@ -388,11 +389,10 @@
 	void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
 		// Builtins do not use autogeneration.
-		if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
-			 aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
+		if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
 			return;
 		}
 
 		// Make function polymorphic in same parameters as generic struct, if applicable
-		const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
+		const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
 
 		// generate each of the functions based on the supplied FuncData objects
@@ -565,5 +565,5 @@
 	}
 
-	void AutogenerateRoutines::previsit( EnumDecl *enumDecl ) {
+	void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
 		visit_children = false;
 		if ( ! enumDecl->get_members().empty() ) {
@@ -574,20 +574,20 @@
 	}
 
-	void AutogenerateRoutines::previsit( StructDecl *structDecl ) {
+	void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
 		visit_children = false;
-		if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
-			StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
-			for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
+		if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
+			StructInstType structInst( Type::Qualifiers(), structDecl->name );
+			for ( TypeDecl * typeDecl : structDecl->parameters ) {
 				// need to visit assertions so that they are added to the appropriate maps
-				acceptAll( typeDecl->get_assertions(), *visitor );
-				structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
+				acceptAll( typeDecl->assertions, *visitor );
+				structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
 			}
 			structInst.set_baseStruct( structDecl );
 			makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
-			structsDone.insert( structDecl->get_name() );
+			structsDone.insert( structDecl->name );
 		} // if
 	}
 
-	void AutogenerateRoutines::previsit( UnionDecl *unionDecl ) {
+	void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
 		visit_children = false;
 		if ( ! unionDecl->get_members().empty() ) {
@@ -609,5 +609,5 @@
 
 	// generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
-	void AutogenerateRoutines::previsit( TypeDecl *typeDecl ) {
+	void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
 		visit_children = false;
 		if ( ! typeDecl->base ) return;
@@ -678,7 +678,7 @@
 		insert( functionDecl, destructable, InitTweak::isDestructor );
 
-		maybeAccept( functionDecl->get_functionType(), *visitor );
+		maybeAccept( functionDecl->type, *visitor );
 		functionNesting += 1;
-		maybeAccept( functionDecl->get_statements(), *visitor );
+		maybeAccept( functionDecl->statements, *visitor );
 		functionNesting -= 1;
 	}
Index: src/SymTab/FixFunction.cc
===================================================================
--- src/SymTab/FixFunction.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/FixFunction.cc	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -27,8 +27,8 @@
 
 	DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
+		// can't delete function type because it may contain assertions, so transfer ownership to new object
 		ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() );
 		functionDecl->get_attributes().clear();
-		// can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr
-		functionDecl->set_type( functionDecl->get_type()->clone() );
+		functionDecl->type = nullptr;
 		delete functionDecl;
 		return pointer;
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/Indexer.cc	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -40,17 +40,4 @@
 
 namespace SymTab {
-	struct NewScope {
-		NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }
-		~NewScope() { indexer.leaveScope(); }
-		SymTab::Indexer & indexer;
-	};
-
-	template< typename TreeType, typename VisitorType >
-	inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
-		visitor.enterScope();
-		maybeAccept( tree, visitor );
-		visitor.leaveScope();
-	}
-
 	typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
 	typedef std::unordered_map< std::string, MangleTable > IdTable;
@@ -198,9 +185,9 @@
 	}
 
-	Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
-
-	Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
-
-	Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
+	Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
+
+	Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
+
+	Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
 		that.tables = 0;
 	}
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/Indexer.h	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -26,5 +26,5 @@
 	class Indexer {
 	  public:
-		explicit Indexer( bool useDebug = false );
+		explicit Indexer();
 
 		Indexer( const Indexer &that );
@@ -76,4 +76,5 @@
 		void addTrait( TraitDecl *decl );
 
+		bool doDebug = false; ///< Display debugging trace?
 	  private:
 		struct Impl;
@@ -81,5 +82,4 @@
 		Impl *tables;         ///< Copy-on-write instance of table data structure
 		unsigned long scope;  ///< Scope index of this pointer
-		bool doDebug;         ///< Display debugging trace?
 
 		/// Takes a new ref to a table (returns null if null)
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/Mangler.cc	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -31,5 +31,5 @@
 
 namespace SymTab {
-	std::string Mangler::mangleType( Type *ty ) {
+	std::string Mangler::mangleType( Type * ty ) {
 		Mangler mangler( false, true );
 		maybeAccept( ty, mangler );
@@ -48,5 +48,5 @@
 	}
 
-	void Mangler::mangleDecl( DeclarationWithType *declaration ) {
+	void Mangler::mangleDecl( DeclarationWithType * declaration ) {
 		bool wasTopLevel = isTopLevel;
 		if ( isTopLevel ) {
@@ -79,18 +79,18 @@
 	}
 
-	void Mangler::visit( ObjectDecl *declaration ) {
+	void Mangler::visit( ObjectDecl * declaration ) {
 		mangleDecl( declaration );
 	}
 
-	void Mangler::visit( FunctionDecl *declaration ) {
+	void Mangler::visit( FunctionDecl * declaration ) {
 		mangleDecl( declaration );
 	}
 
-	void Mangler::visit( VoidType *voidType ) {
+	void Mangler::visit( VoidType * voidType ) {
 		printQualifiers( voidType );
 		mangleName << "v";
 	}
 
-	void Mangler::visit( BasicType *basicType ) {
+	void Mangler::visit( BasicType * basicType ) {
 		static const char *btLetter[] = {
 			"b",	// Bool
@@ -121,5 +121,5 @@
 	}
 
-	void Mangler::visit( PointerType *pointerType ) {
+	void Mangler::visit( PointerType * pointerType ) {
 		printQualifiers( pointerType );
 		mangleName << "P";
@@ -127,5 +127,5 @@
 	}
 
-	void Mangler::visit( ArrayType *arrayType ) {
+	void Mangler::visit( ArrayType * arrayType ) {
 		// TODO: encode dimension
 		printQualifiers( arrayType );
@@ -134,5 +134,5 @@
 	}
 
-	void Mangler::visit( ReferenceType *refType ) {
+	void Mangler::visit( ReferenceType * refType ) {
 		printQualifiers( refType );
 		mangleName << "R";
@@ -149,5 +149,5 @@
 	}
 
-	void Mangler::visit( FunctionType *functionType ) {
+	void Mangler::visit( FunctionType * functionType ) {
 		printQualifiers( functionType );
 		mangleName << "F";
@@ -160,5 +160,5 @@
 	}
 
-	void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
+	void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
 		printQualifiers( refType );
 
@@ -166,5 +166,5 @@
 	}
 
-	void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
+	void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {
 		printQualifiers( refType );
 
@@ -189,19 +189,19 @@
 	}
 
-	void Mangler::visit( StructInstType *aggregateUseType ) {
+	void Mangler::visit( StructInstType * aggregateUseType ) {
 		if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
 		else mangleRef( aggregateUseType, "s" );
 	}
 
-	void Mangler::visit( UnionInstType *aggregateUseType ) {
+	void Mangler::visit( UnionInstType * aggregateUseType ) {
 		if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
 		else mangleRef( aggregateUseType, "u" );
 	}
 
-	void Mangler::visit( EnumInstType *aggregateUseType ) {
+	void Mangler::visit( EnumInstType * aggregateUseType ) {
 		mangleRef( aggregateUseType, "e" );
 	}
 
-	void Mangler::visit( TypeInstType *typeInst ) {
+	void Mangler::visit( TypeInstType * typeInst ) {
 		VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
 		if ( varNum == varNums.end() ) {
@@ -231,27 +231,27 @@
 	}
 
-	void Mangler::visit( TupleType *tupleType ) {
+	void Mangler::visit( TupleType * tupleType ) {
 		printQualifiers( tupleType );
 		mangleName << "T";
-		acceptAll( tupleType->get_types(), *this );
+		acceptAll( tupleType->types, *this );
 		mangleName << "_";
 	}
 
-	void Mangler::visit( VarArgsType *varArgsType ) {
+	void Mangler::visit( VarArgsType * varArgsType ) {
 		printQualifiers( varArgsType );
 		mangleName << "VARGS";
 	}
 
-	void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
+	void Mangler::visit( ZeroType * ) {
 		mangleName << "Z";
 	}
 
-	void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
+	void Mangler::visit( OneType * ) {
 		mangleName << "O";
 	}
 
-	void Mangler::visit( TypeDecl *decl ) {
+	void Mangler::visit( TypeDecl * decl ) {
 		static const char *typePrefix[] = { "BT", "BD", "BF" };
-		mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
+		mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
 	}
 
@@ -262,5 +262,5 @@
 	}
 
-	void Mangler::printQualifiers( Type *type ) {
+	void Mangler::printQualifiers( Type * type ) {
 		// skip if not including qualifiers
 		if ( typeMode ) return;
@@ -270,5 +270,5 @@
 			int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
 			mangleName << "A";
-			for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+			for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
 				switch ( (*i)->get_kind() ) {
 				  case TypeDecl::Any:
@@ -287,6 +287,6 @@
 					assert( false );
 				} // switch
-				varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
-				for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
+				varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
+				for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
 					Mangler sub_mangler( mangleOverridable, typeMode );
 					sub_mangler.nextVarNum = nextVarNum;
@@ -311,7 +311,4 @@
 //			mangleName << "E";
 //		} // if
-		if ( type->get_lvalue() ) {
-			mangleName << "L";
-		} // if
 		if ( type->get_atomic() ) {
 			mangleName << "A";
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/SymTab/Validate.cc	(revision 8b11840bc25cf6e5bbf2f00d4d19a1bf1d24e570)
@@ -56,4 +56,5 @@
 #include "FixFunction.h"               // for FixFunction
 #include "Indexer.h"                   // for Indexer
+#include "InitTweak/GenInit.h"         // for fixReturnStatements
 #include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
 #include "Parser/LinkageSpec.h"        // for C
@@ -150,6 +151,6 @@
 	/// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
 	struct ForallPointerDecay final {
-		void previsit( ObjectDecl *object );
-		void previsit( FunctionDecl *func );
+		void previsit( ObjectDecl * object );
+		void previsit( FunctionDecl * func );
 	};
 
@@ -268,4 +269,5 @@
 		acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
 		acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
+		acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines
 		VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
 		Concurrency::applyKeywords( translationUnit );
@@ -275,5 +277,4 @@
 		ReturnChecker::checkFunctionReturns( translationUnit );
 		mutateAll( translationUnit, compoundliteral );
-		acceptAll( translationUnit, fpd );
 		ArrayLength::computeLength( translationUnit );
 		acceptAll( translationUnit, finder );
@@ -579,6 +580,6 @@
 
 	/// Fix up assertions - flattens assertion lists, removing all trait instances
-	void forallFixer( Type * func ) {
-		for ( TypeDecl * type : func->get_forall() ) {
+	void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
+		for ( TypeDecl * type : forall ) {
 			std::list< DeclarationWithType * > asserts;
 			asserts.splice( asserts.end(), type->assertions );
@@ -599,5 +600,5 @@
 				assertion = assertion->acceptMutator( fixer );
 				if ( fixer.get_isVoid() ) {
-					throw SemanticError( "invalid type void in assertion of function ", func );
+					throw SemanticError( "invalid type void in assertion of function ", node );
 				} // if
 			} // for
@@ -607,7 +608,7 @@
 
 	void ForallPointerDecay::previsit( ObjectDecl *object ) {
-		forallFixer( object->get_type() );
-		if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
-			forallFixer( pointer->get_base() );
+		forallFixer( object->type->forall, object );
+		if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
+			forallFixer( pointer->base->forall, object );
 		} // if
 		object->fixUniqueId();
@@ -615,5 +616,5 @@
 
 	void ForallPointerDecay::previsit( FunctionDecl *func ) {
-		forallFixer( func->get_type() );
+		forallFixer( func->type->forall, func );
 		func->fixUniqueId();
 	}
