Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision b81adcc465c4f2e9cfa5a06860250151ee01113e)
+++ src/InitTweak/FixGlobalInit.cc	(revision 6cf27a070551542d34340180263c714585975c85)
@@ -97,6 +97,4 @@
 		std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
 
-		if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
-		if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
 		// C allows you to initialize objects with constant expressions
 		// xxx - this is an optimization. Need to first resolve constructors before we decide
@@ -104,18 +102,27 @@
 		// if ( isConstExpr( objDecl->get_init() ) ) return;
 
-		if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
-			// xxx - initialize each element of the array
-		} else {
-			// insert constructor for objDecl into global init function
-			UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
-			init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			init->get_args().splice( init->get_args().end(), makeInitList( objDecl->get_init() ) );
-			objDecl->set_init( NULL );
-			initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
+		if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
+			// a decision should have been made by the resolver, so ctor and init are not both non-NULL
+			assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
 
-			// add destructor calls to global destroy function
-			UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
-			destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
+			Statement * dtor = ctorInit->get_dtor();
+			if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
+				// don't need to call intrinsic dtor, because it does nothing, but
+				// non-intrinsic dtors must be called
+				destroyStatements.push_front( dtor );
+				ctorInit->set_dtor( NULL );
+			} // if
+			if ( Statement * ctor = ctorInit->get_ctor() ) {
+				initStatements.push_back( ctor );
+				objDecl->set_init( NULL );
+				ctorInit->set_ctor( NULL );
+			} else if ( Initializer * init = ctorInit->get_init() ) {
+				objDecl->set_init( init );
+				ctorInit->set_init( NULL );
+			} else {
+				// no constructor and no initializer, which is okay
+				objDecl->set_init( NULL );
+			} // if
+			delete ctorInit;
 		} // if
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision b81adcc465c4f2e9cfa5a06860250151ee01113e)
+++ src/InitTweak/FixInit.cc	(revision 6cf27a070551542d34340180263c714585975c85)
@@ -18,6 +18,7 @@
 #include <iterator>
 #include <algorithm>
+#include "InitTweak.h"
 #include "FixInit.h"
-#include "InitTweak.h"
+#include "FixGlobalInit.h"
 #include "ResolvExpr/Resolver.h"
 #include "ResolvExpr/typeops.h"
@@ -83,4 +84,5 @@
 		};
 
+		// debug
 		struct printSet {
 			typedef ObjDeclCollector::ObjectSet ObjectSet;
@@ -171,5 +173,8 @@
 	} // namespace
 
-	void fix( std::list< Declaration * > & translationUnit ) {
+	void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
+		// fixes ConstructorInit for global variables. should happen before fixInitializers.
+		InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
+
 		InsertImplicitCalls::insert( translationUnit );
 		ResolveCopyCtors::resolveImplicitCalls( translationUnit );
Index: src/InitTweak/FixInit.h
===================================================================
--- src/InitTweak/FixInit.h	(revision b81adcc465c4f2e9cfa5a06860250151ee01113e)
+++ src/InitTweak/FixInit.h	(revision 6cf27a070551542d34340180263c714585975c85)
@@ -27,5 +27,5 @@
   /// replace constructor initializers with expression statements
   /// and unwrap basic C-style initializers
-	void fix( std::list< Declaration * > & translationUnit );
+	void fix( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
 } // namespace
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision b81adcc465c4f2e9cfa5a06860250151ee01113e)
+++ src/InitTweak/GenInit.cc	(revision 6cf27a070551542d34340180263c714585975c85)
@@ -61,6 +61,4 @@
 		static void generateCtorDtor( std::list< Declaration * > &translationUnit );
 
-		CtorDtor() : inFunction( false ) {}
-
 		virtual DeclarationWithType * mutate( ObjectDecl * );
 		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
@@ -77,5 +75,4 @@
 
 	  protected:
-		bool inFunction;
 	};
 
@@ -216,53 +213,55 @@
 
 	DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
-		// hands off if designated or if @=
+		// hands off if designated, if @=, or if extern
 		if ( tryConstruct( objDecl ) ) {
-			if ( inFunction ) {
-				if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
-					// call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
-					// TODO: walk initializers and generate appropriate ctor if element has initializer.
-					// Initializer could be nested (depends on the depth of the array type on the object)
-
-					std::list< Expression * > args = makeInitList( objDecl->get_init() );
-					if ( args.empty() ) {
-						std::list< Statement * > ctor;
-						std::list< Statement * > dtor;
-
-						SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
-						SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
-
-						// Currently genArrayCall produces a single Statement - a CompoundStmt
-						// which  wraps everything that needs to happen. As such, it's technically
-						// possible to use a Statement ** in the above calls, but this is inherently
-						// unsafe, so instead we take the slightly less efficient route, but will be
-						// immediately informed if somehow the above assumption is broken. In this case,
-						// we could always wrap the list of statements at this point with a CompoundStmt,
-						// but it seems reasonable at the moment for this to be done by genArrayCall
-						// itself
-						assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) );
-						assert( dtor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( dtor.front() ) );
+			if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
+				// call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
+				// TODO: walk initializers and generate appropriate ctor if element has initializer.
+				// Initializer could be nested (depends on the depth of the array type on the object)
+
+				std::list< Expression * > args = makeInitList( objDecl->get_init() );
+				if ( args.empty() ) {
+					std::list< Statement * > ctor;
+					std::list< Statement * > dtor;
+
+					SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
+					SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
+
+					// Currently genImplicitCall produces a single Statement - a CompoundStmt
+					// which  wraps everything that needs to happen. As such, it's technically
+					// possible to use a Statement ** in the above calls, but this is inherently
+					// unsafe, so instead we take the slightly less efficient route, but will be
+					// immediately informed if somehow the above assumption is broken. In this case,
+					// we could always wrap the list of statements at this point with a CompoundStmt,
+					// but it seems reasonable at the moment for this to be done by genImplicitCall
+					// itself. It is possible that genImplicitCall produces no statements (e.g. if
+					// an array type does not have a dimension). In this case, it's fine to ignore
+					// the object for the purposes of construction.
+					assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
+					if ( ctor.size() == 1 ) {
+						assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
 						objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
-					} else {
-						// array came with an initializer list: initialize each element
-						// may have more initializers than elements in the array - need to check at each index that
-						// we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
-						// computation.
-						// may have fewer initializers than elements in the array - need to default construct
-						// remaining elements.
-						// might be able to merge this with the case above.
-
 					}
 				} else {
-					// it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
-					Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
-					Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
-
-					// need to remember init expression, in case no ctors exist
-					// if ctor does exist, want to use ctor expression instead of init
-					// push this decision to the resolver
-					ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
-					ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
-					objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
+					// array came with an initializer list: initialize each element
+					// may have more initializers than elements in the array - need to check at each index that
+					// we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
+					// computation.
+					// may have fewer initializers than elements in the array - need to default construct
+					// remaining elements.
+					// might be able to merge this with the case above.
+
 				}
+			} else {
+				// it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
+				Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
+				Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
+
+				// need to remember init expression, in case no ctors exist
+				// if ctor does exist, want to use ctor expression instead of init
+				// push this decision to the resolver
+				ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
+				ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
+				objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
 			}
 		}
@@ -272,9 +271,6 @@
 	DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
 		// parameters should not be constructed and destructed, so don't mutate FunctionType
-		bool oldInFunc = inFunction;
 		mutateAll( functionDecl->get_oldDecls(), *this );
-		inFunction = true;
 		functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
-		inFunction = oldInFunc;
 		return functionDecl;
 	}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision b81adcc465c4f2e9cfa5a06860250151ee01113e)
+++ src/InitTweak/InitTweak.cc	(revision 6cf27a070551542d34340180263c714585975c85)
@@ -57,5 +57,6 @@
 			(objDecl->get_init() == NULL ||
 				( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
-			! isDesignated( objDecl->get_init() );
+			! isDesignated( objDecl->get_init() )
+			&& objDecl->get_storageClass() != DeclarationNode::Extern;
 	}
 
