Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/AST/Convert.cpp	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -2764,5 +2764,5 @@
 			old->location,
 			GET_ACCEPT_1(value, Expr),
-			(old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
+			(old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
 		);
 	}
@@ -2773,5 +2773,5 @@
 			GET_ACCEPT_V(initializers, Init),
 			GET_ACCEPT_V(designations, Designation),
-			(old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
+			(old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
 		);
 	}
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/AST/Decl.hpp	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -79,4 +79,5 @@
 	ptr<Expr> asmName;
 	bool isDeleted = false;
+	bool isTypeFixed = false;
 
 	DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
Index: src/AST/Init.hpp
===================================================================
--- src/AST/Init.hpp	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/AST/Init.hpp	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -50,5 +50,5 @@
 
 /// Flag for whether to construct from initialzier
-enum ConstructFlag { DoConstruct, MaybeConstruct };
+enum ConstructFlag { NoConstruct, MaybeConstruct };
 
 /// Object initializer base class
@@ -71,5 +71,5 @@
 	ptr<Expr> value;
 
-	SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = DoConstruct )
+	SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = NoConstruct )
 	: Init( loc, mc ), value( val ) {}
 
@@ -90,5 +90,5 @@
 
 	ListInit( const CodeLocation & loc, std::vector<ptr<Init>> && is,
-		std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = DoConstruct );
+		std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = NoConstruct );
 
 	using iterator = std::vector<ptr<Init>>::iterator;
@@ -118,5 +118,5 @@
 	ConstructorInit( 
 		const CodeLocation & loc, const Stmt * ctor, const Stmt * dtor, const Init * init )
-	: Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
+	: Init( loc, MaybeConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
 
 	const Init * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/AST/Pass.impl.hpp	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -683,7 +683,13 @@
 		// Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
 		auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
-			if ( enterScope ) __pass::symtab::enter(core, 0);
+			if ( enterScope ) {
+				__pass::symtab::enter(core, 0);
+				__pass::scope::enter(core, 0);
+			}
 		}, [this, leaveScope = !this->atFunctionTop]() {
-			if ( leaveScope ) __pass::symtab::leave(core, 0);
+			if ( leaveScope ) {
+				__pass::symtab::leave(core, 0);
+				__pass::scope::leave(core, 0);
+			}
 		});
 		ValueGuard< bool > guard2( atFunctionTop );
Index: src/AST/Type.cpp
===================================================================
--- src/AST/Type.cpp	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/AST/Type.cpp	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -211,5 +211,5 @@
 	for ( const Type * ty : types ) {
 		members.emplace_back( new ObjectDecl{
-			CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ),
+			CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),
 			Storage::Classes{}, Linkage::Cforall } );
 	}
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/CodeGen/CodeGenerator.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -120,5 +120,5 @@
 		// GCC builtins should always be printed unmangled
 		if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
-		if ( decl->mangleName != "" ) {
+		if ( LinkageSpec::isMangled(decl->linkage) && decl->mangleName != "" ) {
 			// need to incorporate scope level in order to differentiate names for destructors
 			return decl->get_scopedMangleName();
Index: src/CodeGen/FixMain.cc
===================================================================
--- src/CodeGen/FixMain.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/CodeGen/FixMain.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -26,4 +26,5 @@
 #include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
 #include "SynTree/Type.h"          // for FunctionType
+#include "SymTab/Mangler.h"
 
 namespace CodeGen {
@@ -47,4 +48,5 @@
 		if( main_signature ) {
 			os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
+			main_signature->mangleName = SymTab::Mangler::mangle(main_signature.get());
 
 			os << main_signature->get_scopedMangleName() << "(";
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/CodeGen/FixNames.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -31,4 +31,5 @@
 #include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
 #include "SynTree/Visitor.h"       // for Visitor, acceptAll
+#include "CompilationState.h"
 
 namespace CodeGen {
@@ -102,5 +103,7 @@
 		if ( dwt->get_name() != "" ) {
 			if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
-				dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
+				if (!useNewAST) {
+					dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
+				}
 				dwt->set_scopeLevel( scopeLevel );
 			} // if
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/InitTweak/GenInit.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -26,4 +26,5 @@
 #include "AST/Node.hpp"
 #include "AST/Stmt.hpp"
+#include "CompilationState.h"
 #include "CodeGen/OperatorTable.h"
 #include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
@@ -122,7 +123,10 @@
 
 	void genInit( std::list< Declaration * > & translationUnit ) {
+		HoistArrayDimension::hoistArrayDimension( translationUnit );
 		fixReturnStatements( translationUnit );
-		HoistArrayDimension::hoistArrayDimension( translationUnit );
-		CtorDtor::generateCtorDtor( translationUnit );
+
+		if (!useNewAST) {
+			CtorDtor::generateCtorDtor( translationUnit );
+		}
 	}
 
@@ -192,9 +196,14 @@
 
 			// need to resolve array dimensions in order to accurately determine if constexpr
-			ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
-			// array is variable-length when the dimension is not constexpr
-			arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
+			if (!useNewAST) {
+				ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
+				// array is variable-length when the dimension is not constexpr
+				arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
+			}
 			// don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
-			if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
+			// xxx - hoisting has no side effects anyways, so don't skip since we delay resolve	
+			// only skip in the most trivial case, which does not require resolve
+			if (dynamic_cast<ConstantExpr *>(arrayType->dimension)) return;
+			// if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
 
 			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
@@ -245,4 +254,5 @@
 	}
 
+	// why is this not just on FunctionDecl?
 	void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
 		// if this function is a user-defined constructor or destructor, mark down the type as "managed"
@@ -274,4 +284,63 @@
 	void ManagedTypes::beginScope() { managedTypes.beginScope(); }
 	void ManagedTypes::endScope() { managedTypes.endScope(); }
+
+	bool ManagedTypes_new::isManaged( const ast::Type * type ) const {
+		// references are never constructed
+		if ( dynamic_cast< const ast::ReferenceType * >( type ) ) return false;
+		if ( auto tupleType = dynamic_cast< const ast::TupleType * > ( type ) ) {
+			// tuple is also managed if any of its components are managed
+			for (auto & component : tupleType->types) {
+				if (isManaged(component)) return true;
+			}
+		}
+		// need to clear and reset qualifiers when determining if a type is managed
+		// ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );
+		auto tmp = shallowCopy(type);
+		tmp->qualifiers = {};
+		// delete tmp at return
+		ast::ptr<ast::Type> guard = tmp;
+		// a type is managed if it appears in the map of known managed types, or if it contains any polymorphism (is a type variable or generic type containing a type variable)
+		return managedTypes.find( Mangle::mangle( tmp, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ) != managedTypes.end() || GenPoly::isPolyType( tmp );
+	}
+
+	bool ManagedTypes_new::isManaged( const ast::ObjectDecl * objDecl ) const {
+		const ast::Type * type = objDecl->type;
+		while ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
+			// must always construct VLAs with an initializer, since this is an error in C
+			if ( at->isVarLen && objDecl->init ) return true;
+			type = at->base;
+		}
+		return isManaged( type );
+	}
+
+	void ManagedTypes_new::handleDWT( const ast::DeclWithType * dwt ) {
+		// if this function is a user-defined constructor or destructor, mark down the type as "managed"
+		if ( ! dwt->linkage.is_overrideable && CodeGen::isCtorDtor( dwt->name ) ) {
+			auto & params = GenPoly::getFunctionType( dwt->get_type())->params;
+			assert( ! params.empty() );
+			// Type * type = InitTweak::getPointerBase( params.front() );
+			// assert( type );
+			managedTypes.insert( Mangle::mangle( params.front(), {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
+		}
+	}
+
+	void ManagedTypes_new::handleStruct( const ast::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 ( auto & member : aggregateDecl->members ) {
+			if ( auto field = member.as<ast::ObjectDecl>() ) {
+				if ( isManaged( field ) ) {
+					// 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
+					ast::StructInstType inst( aggregateDecl );
+					managedTypes.insert( Mangle::mangle( &inst, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
+					break;
+				}
+			}
+		}
+	}
+
+	void ManagedTypes_new::beginScope() { managedTypes.beginScope(); }
+	void ManagedTypes_new::endScope() { managedTypes.endScope(); }
 
 	ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
@@ -370,9 +439,10 @@
 	// constructable object
 	InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
+	ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl);
 	
 	ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 
-		srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
+		srcParam, dstParam, loc, "?{}", objDecl );
 	ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 
-		nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl, 
+		nullParam, dstParam, loc, "^?{}", objDecl, 
 		SymTab::LoopBackward );
 	
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/InitTweak/GenInit.h	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -52,4 +52,18 @@
 		GenPoly::ScopedSet< std::string > managedTypes;
 	};
+
+	class ManagedTypes_new {
+	public:
+		bool isManaged( const ast::ObjectDecl * objDecl ) const ; // determine if object is managed
+		bool isManaged( const ast::Type * type ) const; // determine if type is managed
+
+		void handleDWT( const ast::DeclWithType * dwt ); // add type to managed if ctor/dtor
+		void handleStruct( const ast::StructDecl * aggregateDecl ); // add type to managed if child is managed
+
+		void beginScope();
+		void endScope();
+	private:
+		GenPoly::ScopedSet< std::string > managedTypes;
+	};
 } // namespace
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/InitTweak/InitTweak.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -87,4 +87,41 @@
 		};
 
+		struct HasDesignations_new : public ast::WithShortCircuiting {
+			bool result = false;
+
+			void previsit( const ast::Node * ) {
+				// short circuit if we already know there are designations
+				if ( result ) visit_children = false;
+			}
+
+			void previsit( const ast::Designation * des ) {
+				// short circuit if we already know there are designations
+				if ( result ) visit_children = false;
+				else if ( ! des->designators.empty() ) {
+					result = true;
+					visit_children = false;
+				}
+			}
+		};
+
+		struct InitDepthChecker_new : public ast::WithGuards {
+			bool result = true;
+			const ast::Type * type;
+			int curDepth = 0, maxDepth = 0;
+			InitDepthChecker_new( const ast::Type * type ) : type( type ) {
+				const ast::Type * t = type;
+				while ( auto at = dynamic_cast< const ast::ArrayType * >( t ) ) {
+					maxDepth++;
+					t = at->base;
+				}
+				maxDepth++;
+			}
+			void previsit( ListInit * ) {
+				curDepth++;
+				GuardAction( [this]() { curDepth--; } );
+				if ( curDepth > maxDepth ) result = false;
+			}
+		};
+
 		struct InitFlattener_old : public WithShortCircuiting {
 			void previsit( SingleInit * singleInit ) {
@@ -122,4 +159,16 @@
 		maybeAccept( objDecl->init, checker );
 		return checker.pass.depthOkay;
+	}
+
+	bool isDesignated( const ast::Init * init ) {
+		ast::Pass<HasDesignations_new> finder;
+		maybe_accept( init, finder );
+		return finder.core.result;
+	}
+
+	bool checkInitDepth( const ast::ObjectDecl * objDecl ) {
+		ast::Pass<InitDepthChecker_new> checker( objDecl->type );
+		maybe_accept( objDecl->init.get(), checker );
+		return checker.core.result;
 	}
 
@@ -358,8 +407,8 @@
 			if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
 				for ( const ast::Init * init : *listInit ) {
-					buildCallExpr( callExpr, index, dimension, init, out );
+					buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
 				}
 			} else {
-				buildCallExpr( callExpr, index, dimension, init, out );
+				buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
 			}
 		} else {
@@ -1027,4 +1076,47 @@
 	};
 
+	struct ConstExprChecker_new : public ast::WithShortCircuiting {
+		// most expressions are not const expr
+		void previsit( const ast::Expr * ) { result = false; visit_children = false; }
+
+		void previsit( const ast::AddressExpr *addressExpr ) {
+			visit_children = false;
+			const ast::Expr * arg = addressExpr->arg;
+
+			// address of a variable or member expression is constexpr
+			if ( ! dynamic_cast< const ast::NameExpr * >( arg ) 
+			&& ! dynamic_cast< const ast::VariableExpr * >( arg ) 
+			&& ! dynamic_cast< const ast::MemberExpr * >( arg ) 
+			&& ! dynamic_cast< const ast::UntypedMemberExpr * >( arg ) ) result = false;
+		}
+
+		// these expressions may be const expr, depending on their children
+		void previsit( const ast::SizeofExpr * ) {}
+		void previsit( const ast::AlignofExpr * ) {}
+		void previsit( const ast::UntypedOffsetofExpr * ) {}
+		void previsit( const ast::OffsetofExpr * ) {}
+		void previsit( const ast::OffsetPackExpr * ) {}
+		void previsit( const ast::CommaExpr * ) {}
+		void previsit( const ast::LogicalExpr * ) {}
+		void previsit( const ast::ConditionalExpr * ) {}
+		void previsit( const ast::CastExpr * ) {}
+		void previsit( const ast::ConstantExpr * ) {}
+
+		void previsit( const ast::VariableExpr * varExpr ) {
+			visit_children = false;
+
+			if ( auto inst = varExpr->result.as<ast::EnumInstType>() ) {
+				long long int value;
+				if ( inst->base->valueOf( varExpr->var, value ) ) {
+					// enumerators are const expr
+					return;
+				}
+			}
+			result = false;
+		}
+
+		bool result = true;
+	};
+
 	bool isConstExpr( Expression * expr ) {
 		if ( expr ) {
@@ -1046,4 +1138,23 @@
 	}
 
+	bool isConstExpr( const ast::Expr * expr ) {
+		if ( expr ) {
+			ast::Pass<ConstExprChecker_new> checker;
+			expr->accept( checker );
+			return checker.core.result;
+		}
+		return true;
+	}
+
+	bool isConstExpr( const ast::Init * init ) {
+		if ( init ) {
+			ast::Pass<ConstExprChecker_new> checker;
+			init->accept( checker );
+			return checker.core.result;
+		} // if
+		// for all intents and purposes, no initializer means const expr
+		return true;
+	}
+
 	bool isConstructor( const std::string & str ) { return str == "?{}"; }
 	bool isDestructor( const std::string & str ) { return str == "^?{}"; }
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/InitTweak/InitTweak.h	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -59,8 +59,10 @@
 	/// True if the Initializer contains designations
 	bool isDesignated( Initializer * init );
+	bool isDesignated( const ast::Init * init );
 
 	/// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its
 	/// type, where the depth of its type is the number of nested ArrayTypes + 1
 	bool checkInitDepth( ObjectDecl * objDecl );
+	bool checkInitDepth( const ast::ObjectDecl * objDecl );
 
 	/// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
@@ -107,4 +109,7 @@
 	bool isConstExpr( Expression * expr );
 	bool isConstExpr( Initializer * init );
+
+	bool isConstExpr( const ast::Expr * expr );
+	bool isConstExpr( const ast::Init * init );
 
 	/// Modifies objDecl to have:
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -29,4 +29,6 @@
 #include "SynTree/Mutator.h"     // for Mutator
 #include "SynTree/Type.h"        // for TypeofType, Type
+#include "SymTab/Mangler.h"
+#include "InitTweak/InitTweak.h" // for isConstExpr
 
 namespace SymTab {
@@ -163,4 +165,31 @@
 }
 
+const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) {
+	if (!decl->isTypeFixed) { 
+		auto mutDecl = mutate(decl);
+		auto resolvedType = resolveTypeof(decl->type, symtab);
+		mutDecl->type = resolvedType;
+
+		// check variable length if object is an array.
+		// xxx - should this be part of fixObjectType?
+		if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
+			if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
+				if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
+					auto mutType = mutate(arrayType);
+					mutType->isVarLen = ast::LengthFlag::VariableLen;
+					mutDecl->type = mutType;
+				}
+			}
+		}
+
+		if (!mutDecl->name.empty()) 
+			mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
+		
+		mutDecl->isTypeFixed = true;
+		return mutDecl;
+	}
+	return decl;
+}
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ResolveTypeof.h
===================================================================
--- src/ResolvExpr/ResolveTypeof.h	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/ResolvExpr/ResolveTypeof.h	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -23,4 +23,5 @@
 	class Type;
 	class SymbolTable;
+	class ObjectDecl;
 }
 
@@ -28,4 +29,5 @@
 	Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
 	const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
+	const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/ResolvExpr/Resolver.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -26,7 +26,9 @@
 #include "RenameVars.h"                  // for RenameVars, global_renamer
 #include "Resolver.h"
+#include "ResolveTypeof.h"
 #include "ResolvMode.h"                  // for ResolvMode
 #include "typeops.h"                     // for extractResultType
 #include "Unify.h"                       // for unify
+#include "CompilationState.h"
 #include "AST/Chain.hpp"
 #include "AST/Decl.hpp"
@@ -45,4 +47,5 @@
 #include "SymTab/Autogen.h"              // for SizeType
 #include "SymTab/Indexer.h"              // for Indexer
+#include "SymTab/Mangler.h"              // for Mangler
 #include "SynTree/Declaration.h"         // for ObjectDecl, TypeDecl, Declar...
 #include "SynTree/Expression.h"          // for Expression, CastExpr, InitExpr
@@ -1179,15 +1182,19 @@
 	} // anonymous namespace
 
-		ast::ptr< ast::Expr > findSingleExpression(
-			const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
-		) {
-			assert( untyped && type );
-			ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
-			ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
-			removeExtraneousCast( newExpr, symtab );
-			return newExpr;
-		}
+	ast::ptr< ast::Expr > findSingleExpression(
+		const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
+	) {
+		assert( untyped && type );
+		ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
+		ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
+		removeExtraneousCast( newExpr, symtab );
+		return newExpr;
+	}
 
 	namespace {
+		bool structOrUnion( const Candidate & i ) {
+			const ast::Type * t = i.expr->result->stripReferences();
+			return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t );
+		}
 		/// Predicate for "Candidate has integral type"
 		bool hasIntegralType( const Candidate & i ) {
@@ -1237,4 +1244,7 @@
 		ast::ptr< ast::Type > functionReturn = nullptr;
 		ast::CurrentObject currentObject;
+		// for work previously in GenInit
+		static InitTweak::ManagedTypes_new managedTypes;
+
 		bool inEnumDecl = false;
 
@@ -1244,7 +1254,9 @@
 		Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
 
-		void previsit( const ast::FunctionDecl * );
+		const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
 		const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
-		void previsit( const ast::ObjectDecl * );
+		const ast::ObjectDecl * previsit( const ast::ObjectDecl * );
+		void previsit( const ast::AggregateDecl * );
+		void previsit( const ast::StructDecl * );
 		void previsit( const ast::EnumDecl * );
 		const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
@@ -1267,10 +1279,18 @@
 		const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
 		const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
+		const ast::WithStmt *        previsit( const ast::WithStmt * );
 
 		const ast::SingleInit *      previsit( const ast::SingleInit * );
 		const ast::ListInit *        previsit( const ast::ListInit * );
 		const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
+
+		void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd);
+
+		void beginScope() { managedTypes.beginScope(); }
+		void endScope() { managedTypes.endScope(); }
 	};
 	// size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
+
+	InitTweak::ManagedTypes_new Resolver_new::managedTypes;
 
 	void resolve( ast::TranslationUnit& translationUnit ) {
@@ -1297,7 +1317,107 @@
 	}
 
-	void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
+	namespace {
+		const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
+			std::string name = attr->normalizedName();
+			if (name == "constructor" || name == "destructor") {
+				if (attr->params.size() == 1) {
+					auto arg = attr->params.front();
+					auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
+					auto result = eval(arg);
+
+					auto mutAttr = mutate(attr);
+					mutAttr->params.front() = resolved;
+					if (! result.second) {
+						SemanticWarning(loc, Warning::GccAttributes,
+							toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) );
+					}
+					else {
+						auto priority = result.first;
+						if (priority < 101) {
+							SemanticWarning(loc, Warning::GccAttributes,
+								toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) );
+						} else if (priority < 201 && ! buildingLibrary()) {
+							SemanticWarning(loc, Warning::GccAttributes,
+								toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) );
+						}
+					}
+					return mutAttr;
+				} else if (attr->params.size() > 1) {
+					SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) );
+				} else {
+					SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) );
+				}
+			}
+			return attr;
+		}
+	}
+
+	const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
 		GuardValue( functionReturn );
+
+		assert (functionDecl->unique());
+		if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) {
+			SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations");
+		}
+
+		if (!functionDecl->isTypeFixed) {
+			auto mutDecl = mutate(functionDecl);
+			auto mutType = mutDecl->type.get_and_mutate();
+
+			for (auto & attr: mutDecl->attributes) {
+				attr = handleAttribute(mutDecl->location, attr, symtab);
+			}
+
+			// handle assertions. (seems deep)
+
+			symtab.enterScope();
+			for (auto & typeParam : mutType->forall) {
+				auto mutParam = typeParam.get_and_mutate();
+				symtab.addType(mutParam);
+				for (auto & asst : mutParam->assertions) {
+					asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
+					symtab.addId(asst);
+				}
+				typeParam = mutParam;
+			}
+
+			// temporarily adds params to symbol table.
+			// actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl)
+
+			std::vector<ast::ptr<ast::Type>> paramTypes;
+			std::vector<ast::ptr<ast::Type>> returnTypes;
+
+			for (auto & param : mutDecl->params) {
+				param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
+				symtab.addId(param);
+				paramTypes.emplace_back(param->get_type());
+			}
+			for (auto & ret : mutDecl->returns) {
+				ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
+				returnTypes.emplace_back(ret->get_type());
+			}
+			// since function type in decl is just a view of param types, need to update that as well
+			mutType->params = std::move(paramTypes);
+			mutType->returns = std::move(returnTypes);
+
+			std::list<ast::ptr<ast::Stmt>> newStmts;
+			resolveWithExprs (mutDecl->withExprs, newStmts);
+
+			if (mutDecl->stmts) {
+				auto mutStmt = mutDecl->stmts.get_and_mutate();
+				mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts));
+				mutDecl->stmts = mutStmt;
+			}
+
+			symtab.leaveScope();
+
+			mutDecl->mangleName = Mangle::mangle(mutDecl);
+			mutDecl->isTypeFixed = true;
+			functionDecl = mutDecl;
+		}
+		managedTypes.handleDWT(functionDecl);
+
 		functionReturn = extractResultType( functionDecl->type );
+		return functionDecl;
 	}
 
@@ -1330,5 +1450,5 @@
 	}
 
-	void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
+	const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
 		// To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
 		// class-variable `initContext` is changed multiple times because the LHS is analyzed
@@ -1338,11 +1458,53 @@
 		// selecting the RHS.
 		GuardValue( currentObject );
-		currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
+
 		if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
 			// enumerator initializers should not use the enum type to initialize, since the
 			// enum type is still incomplete at this point. Use `int` instead.
+			objectDecl = fixObjectType(objectDecl, symtab);
 			currentObject = ast::CurrentObject{
 				objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
 		}
+		else {
+			if (!objectDecl->isTypeFixed) {
+				auto newDecl = fixObjectType(objectDecl, symtab);
+				auto mutDecl = mutate(newDecl);
+				
+				// generate CtorInit wrapper when necessary.
+				// in certain cases, fixObjectType is called before reaching
+				// this object in visitor pass, thus disabling CtorInit codegen.
+				// this happens on aggregate members and function parameters.
+				if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
+					// constructed objects cannot be designated
+					if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
+					// constructed objects should not have initializers nested too deeply
+					if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
+
+					mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl );
+				}
+
+				objectDecl = mutDecl;
+			}
+			currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
+		}
+		
+		return objectDecl;
+	}
+
+	void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) {
+		auto aggDecl = mutate(_aggDecl);
+		assertf(aggDecl == _aggDecl, "type declarations must be unique");
+
+		for (auto & member: aggDecl->members) {
+			// nested type decls are hoisted already. no need to do anything
+			if (auto obj = member.as<ast::ObjectDecl>()) {
+				member = fixObjectType(obj, symtab);
+			}
+		}
+	}
+
+	void Resolver_new::previsit( const ast::StructDecl * structDecl ) {
+		previsit(static_cast<const ast::AggregateDecl *>(structDecl));
+		managedTypes.handleStruct(structDecl);
 	}
 
@@ -1351,5 +1513,7 @@
 		GuardValue( inEnumDecl );
 		inEnumDecl = true;
-	}
+		// don't need to fix types for enum fields
+	}
+
 
 	const ast::StaticAssertDecl * Resolver_new::previsit(
@@ -1780,4 +1944,31 @@
 	}
 
+	const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) {
+		auto mutStmt = mutate(withStmt);
+		resolveWithExprs(mutStmt->exprs, stmtsToAddBefore);
+		return mutStmt;
+	}
+
+	void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) {
+		for (auto & expr : exprs) {
+			// only struct- and union-typed expressions are viable candidates
+			expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
+
+			// if with expression might be impure, create a temporary so that it is evaluated once
+			if ( Tuples::maybeImpure( expr ) ) {
+				static UniqueName tmpNamer( "_with_tmp_" );
+				const CodeLocation loc = expr->location;
+				auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) );
+				expr = new ast::VariableExpr( loc, tmp );
+				stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) );
+				if ( InitTweak::isConstructable( tmp->type ) ) {
+					// generate ctor/dtor and resolve them
+					tmp->init = InitTweak::genCtorInit( loc, tmp );
+				}
+				// since tmp is freshly created, this should modify tmp in-place
+				tmp->accept( *visitor );
+			}
+		}
+	}
 
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/SymTab/Autogen.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -38,4 +38,5 @@
 #include "SynTree/Type.h"          // for FunctionType, Type, TypeInstType
 #include "SynTree/Visitor.h"       // for maybeAccept, Visitor, acceptAll
+#include "CompilationState.h"
 
 class Attribute;
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/SymTab/Autogen.h	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -167,5 +167,5 @@
 		fExpr->args.emplace_back( dstParam );
 
-		const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
+		ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr );
 
 		// fetch next set of arguments
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 3febb2d624d5513f54b3ec586fb1509c3cbf934b)
+++ src/SymTab/Validate.cc	(revision 16ba4a6fa0eb60a0cd27fb96882e37dbf94834dd)
@@ -64,4 +64,5 @@
 #include "Common/UniqueName.h"         // for UniqueName
 #include "Common/utility.h"            // for operator+, cloneAll, deleteAll
+#include "CompilationState.h"          // skip some passes in new-ast build
 #include "Concurrency/Keywords.h"      // for applyKeywords
 #include "FixFunction.h"               // for FixFunction
@@ -281,5 +282,5 @@
 
 		void previsit( ObjectDecl * objDecl );
-		void previsit( ArrayType * arrayType );
+		// void previsit( ArrayType * arrayType );
 	};
 
@@ -368,13 +369,17 @@
 				mutateAll( translationUnit, compoundliteral );
 			});
-			Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
-				ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
-			});
+			if (!useNewAST) {
+				Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
+					ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
+				});
+			}
 		}
 		{
 			Stats::Heap::newPass("validate-F");
 			Stats::Time::BlockGuard guard("validate-F");
-			Stats::Time::TimeCall("Fix Object Type",
-				FixObjectType::fix, translationUnit);
+			if (!useNewAST) {
+				Stats::Time::TimeCall("Fix Object Type",
+					FixObjectType::fix, translationUnit);
+			}
 			Stats::Time::TimeCall("Array Length",
 				ArrayLength::computeLength, translationUnit);
@@ -383,6 +388,8 @@
 			Stats::Time::TimeCall("Fix Label Address",
 				mutateAll<LabelAddressFixer>, translationUnit, labelAddrFixer);
-			Stats::Time::TimeCall("Handle Attributes",
-				Validate::handleAttributes, translationUnit);
+			if (!useNewAST) {
+				Stats::Time::TimeCall("Handle Attributes",
+					Validate::handleAttributes, translationUnit);
+			}
 		}
 	}
@@ -1339,4 +1346,7 @@
 	}
 
+	// xxx - this seems to be in HoistArrayDimension now.
+
+	/*
 	void ArrayLength::previsit( ArrayType * type ) {
 		if ( type->dimension ) {
@@ -1350,4 +1360,5 @@
 		}
 	}
+	*/
 
 	struct LabelFinder {
