Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
+++ src/InitTweak/FixGlobalInit.cc	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
@@ -0,0 +1,133 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// FixGlobalInit.cc --
+//
+// Author           : Rob Schluntz
+// Created On       : Mon May 04 15:14:56 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed May 04 16:53:12 2016
+// Update Count     : 2
+//
+
+#include "FixGlobalInit.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Visitor.h"
+#include <algorithm>
+
+namespace InitTweak {
+	namespace {
+		const std::list<Label> noLabels;
+	}
+
+	class GlobalFixer : public Visitor {
+	  public:
+		GlobalFixer( const std::string & fileName );
+
+		virtual void visit( ObjectDecl *objDecl );
+		virtual void visit( FunctionDecl *functionDecl );
+
+		UniqueName tempNamer;
+		FunctionDecl * initFunction;
+	};
+
+	class ConstExprChecker : public Visitor {
+	public:
+		ConstExprChecker() : isConstExpr( true ) {}
+
+		virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
+		virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
+		virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
+		virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
+		virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
+		virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
+		virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
+		// these might be okay?
+		// virtual void visit( SizeofExpr *sizeofExpr );
+		// virtual void visit( AlignofExpr *alignofExpr );
+		// virtual void visit( UntypedOffsetofExpr *offsetofExpr );
+		// virtual void visit( OffsetofExpr *offsetofExpr );
+		// virtual void visit( OffsetPackExpr *offsetPackExpr );
+		// virtual void visit( AttrExpr *attrExpr );
+		// virtual void visit( CommaExpr *commaExpr );
+		// virtual void visit( LogicalExpr *logicalExpr );
+		// virtual void visit( ConditionalExpr *conditionalExpr );
+		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
+		virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
+		virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
+
+		bool isConstExpr;
+	};
+
+	bool isConstExpr( Initializer * init ) {
+		if ( init ) {
+			ConstExprChecker checker;
+			init->accept( checker );
+			return checker.isConstExpr;
+		}
+		// for all intents and purposes, no initializer means const expr
+		return true;
+	}
+
+	void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name ) {
+		GlobalFixer fixer( name );
+		acceptAll( translationUnit, fixer );
+		translationUnit.push_back( fixer.initFunction );
+	}
+
+  std::string initName( const std::string & name ) {
+  	// get basename
+  	std::string ret = name.substr( 0, name.find( '.' ) );
+  	// replace invalid characters with _
+		static std::string invalid = "/-";
+  	replace_if( ret.begin(), ret.end(), []( char c ) { return invalid.find(c) != std::string::npos; }, '_' );
+  	return "_init_" + ret;
+  }
+
+	GlobalFixer::GlobalFixer( const std::string & fileName ) : tempNamer( "_global_init" ) {
+		initFunction = new FunctionDecl( initName( fileName ), DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
+	}
+
+	void GlobalFixer::visit( ObjectDecl *objDecl ) {
+		std::list< Statement * > & statements = initFunction->get_statements()->get_kids();
+
+		// C allows you to initialize objects with constant expressions
+		if ( isConstExpr( objDecl->get_init() ) ) return;
+
+		// steal initializer from object and attach it to a new temporary
+		ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
+		objDecl->set_init( NULL );
+		statements.push_back( new DeclStmt( noLabels, newObj ) );
+
+		// assign (later: copy construct) objDecl using temporary
+		UntypedExpr * init = new UntypedExpr( new NameExpr( "?=?" ) );
+		init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
+		init->get_args().push_back( new VariableExpr( newObj ) );
+		statements.push_back( new ExprStmt( noLabels, init ) );
+
+		// xxx- need to destruct objDecl atexit
+	}
+
+	void GlobalFixer::visit( FunctionDecl *functionDecl ) {
+		// only modify global variables
+	}
+} // namespace InitTweak
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/InitTweak/FixGlobalInit.h
===================================================================
--- src/InitTweak/FixGlobalInit.h	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
+++ src/InitTweak/FixGlobalInit.h	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
@@ -0,0 +1,40 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// FixGlobalInit.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Mon May 04 15:14:56 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed May 04 16:35:37 2016
+// Update Count     : 2
+//
+
+#ifndef FIX_GLOBAL_INIT_H
+#define FIX_GLOBAL_INIT_H
+
+#include <string>
+#include <list>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+
+namespace InitTweak {
+  /// Moves global initialization into an _init function that is unique to the translation unit
+  void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name );
+
+  /// Apply transformations to a file name to get a valid C identifier which will be used as
+  /// the name of the generated initializer function.
+  std::string initName( const std::string & name );
+} // namespace
+
+#endif // GENPOLY_POLYMUTATOR_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/InitTweak/module.mk
===================================================================
--- src/InitTweak/module.mk	(revision afc1045a9ddab4e6d7c524844fc6895bf4ef52ec)
+++ src/InitTweak/module.mk	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
@@ -11,8 +11,9 @@
 ## Created On       : Mon Jun  1 17:49:17 2015
 ## Last Modified By : Rob Schluntz
-## Last Modified On : Mon Jan 11 14:40:16 2016
+## Last Modified On : Wed May 04 16:03:49 2016
 ## Update Count     : 2
 ###############################################################################
 
-SRC += InitTweak/RemoveInit.cc
+SRC += InitTweak/RemoveInit.cc \
+	InitTweak/FixGlobalInit.cc
 
