Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 189d8006733bdd60c00694bcd130684d954c88bd)
+++ src/InitTweak/GenInit.cc	(revision bfd4974c5982bdb259066163ce97baab711df4ee)
@@ -85,8 +85,5 @@
 		// should not have a ConstructorInit generated.
 
-		bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
-		bool isManaged( Type * type ) const; // determine if type is managed
-		void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
-		GenPoly::ScopedSet< std::string > managedTypes;
+		ManagedTypes managedTypes;
 		bool inFunction = false;
 	};
@@ -204,5 +201,5 @@
 	}
 
-	bool CtorDtor::isManaged( Type * type ) const {
+	bool ManagedTypes::isManaged( Type * type ) const {
 		// references are never constructed
 		if ( dynamic_cast< ReferenceType * >( type ) ) return false;
@@ -220,5 +217,5 @@
 	}
 
-	bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
+	bool ManagedTypes::isManaged( ObjectDecl * objDecl ) const {
 		Type * type = objDecl->get_type();
 		while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
@@ -228,5 +225,5 @@
 	}
 
-	void CtorDtor::handleDWT( DeclarationWithType * dwt ) {
+	void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
 		// if this function is a user-defined constructor or destructor, mark down the type as "managed"
 		if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && CodeGen::isCtorDtor( dwt->get_name() ) ) {
@@ -238,4 +235,21 @@
 		}
 	}
+
+	void ManagedTypes::handleStruct( StructDecl * aggregateDecl ) {
+		// don't construct members, but need to take note if there is a managed member,
+		// because that means that this type is also managed
+		for ( Declaration * member : aggregateDecl->get_members() ) {
+			if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
+				if ( isManaged( field ) ) {
+					StructInstType inst( Type::Qualifiers(), aggregateDecl );
+					managedTypes.insert( SymTab::Mangler::mangle( &inst ) );
+					break;
+				}
+			}
+		}
+	}
+
+	void ManagedTypes::beginScope() { managedTypes.beginScope(); }
+	void ManagedTypes::endScope() { managedTypes.endScope(); }
 
 	ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
@@ -282,8 +296,8 @@
 
 	void CtorDtor::previsit( ObjectDecl * objDecl ) {
-		handleDWT( objDecl );
+		managedTypes.handleDWT( objDecl );
 		// hands off if @=, extern, builtin, etc.
 		// even if unmanaged, try to construct global or static if initializer is not constexpr, since this is not legal C
-		if ( tryConstruct( objDecl ) && ( isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
+		if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
 			// constructed objects cannot be designated
 			if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n", objDecl );
@@ -300,5 +314,5 @@
 		inFunction = true;
 
-		handleDWT( functionDecl );
+		managedTypes.handleDWT( functionDecl );
 
 		GuardScope( managedTypes );
@@ -306,5 +320,5 @@
 		for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
 			for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
-				handleDWT( assertion );
+				managedTypes.handleDWT( assertion );
 			}
 		}
@@ -316,15 +330,5 @@
 		visit_children = false; // do not try to construct and destruct aggregate members
 
-		// don't construct members, but need to take note if there is a managed member,
-		// because that means that this type is also managed
-		for ( Declaration * member : aggregateDecl->get_members() ) {
-			if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
-				if ( isManaged( field ) ) {
-					StructInstType inst( Type::Qualifiers(), aggregateDecl );
-					managedTypes.insert( SymTab::Mangler::mangle( &inst ) );
-					break;
-				}
-			}
-		}
+		managedTypes.handleStruct( aggregateDecl );
 	}
 
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision 189d8006733bdd60c00694bcd130684d954c88bd)
+++ src/InitTweak/GenInit.h	(revision bfd4974c5982bdb259066163ce97baab711df4ee)
@@ -16,8 +16,10 @@
 #pragma once
 
-#include <list>               // for list
-#include <string>             // for string
+#include <list>                // for list
+#include <string>              // for string
 
-#include "SynTree/SynTree.h"  // for Visitor Nodes
+#include "SynTree/SynTree.h"   // for Visitor Nodes
+
+#include "GenPoly/ScopedSet.h" // for ScopedSet
 
 namespace InitTweak {
@@ -33,4 +35,18 @@
 	/// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
 	ConstructorInit * genCtorInit( ObjectDecl * objDecl );
+
+	class ManagedTypes {
+	public:
+		bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
+		bool isManaged( Type * type ) const; // determine if type is managed
+
+		void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
+		void handleStruct( StructDecl * aggregateDecl ); // add type to managed if child is managed
+
+		void beginScope();
+		void endScope();
+	private:
+		GenPoly::ScopedSet< std::string > managedTypes;
+	};
 } // namespace
 
