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 1b7ea438000707f1b44dd8d1be0ee7f72350dadf)
+++ 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
 
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 1b7ea438000707f1b44dd8d1be0ee7f72350dadf)
+++ src/Makefile.in	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
@@ -124,4 +124,5 @@
 	GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
 	InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
+	InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT) \
 	Parser/driver_cfa_cpp-parser.$(OBJEXT) \
 	Parser/driver_cfa_cpp-lex.$(OBJEXT) \
@@ -346,9 +347,10 @@
 	GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
 	GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \
-	Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
-	Parser/ParseNode.cc Parser/DeclarationNode.cc \
-	Parser/ExpressionNode.cc Parser/StatementNode.cc \
-	Parser/InitializerNode.cc Parser/TypeData.cc \
-	Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
+	InitTweak/FixGlobalInit.cc Parser/parser.yy Parser/lex.ll \
+	Parser/TypedefTable.cc Parser/ParseNode.cc \
+	Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
+	Parser/StatementNode.cc Parser/InitializerNode.cc \
+	Parser/TypeData.cc Parser/LinkageSpec.cc \
+	Parser/parseutility.cc Parser/Parser.cc \
 	ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
 	ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
@@ -562,4 +564,6 @@
 	@: > InitTweak/$(DEPDIR)/$(am__dirstamp)
 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
+	InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
+InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT):  \
 	InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
 Parser/parser.h: Parser/parser.cc
@@ -792,4 +796,5 @@
 	-rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
 	-rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
+	-rm -f InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT)
 	-rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
 	-rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
@@ -897,4 +902,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
@@ -1380,4 +1386,18 @@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-RemoveInit.obj `if test -f 'InitTweak/RemoveInit.cc'; then $(CYGPATH_W) 'InitTweak/RemoveInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/RemoveInit.cc'; fi`
 
+InitTweak/driver_cfa_cpp-FixGlobalInit.o: InitTweak/FixGlobalInit.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
+@am__fastdepCXX_TRUE@	$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
+
+InitTweak/driver_cfa_cpp-FixGlobalInit.obj: InitTweak/FixGlobalInit.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
+
 Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
 @am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 1b7ea438000707f1b44dd8d1be0ee7f72350dadf)
+++ src/main.cc	(revision 711eee5ec8d25e9626c493d8242244335aa1f547)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// main.cc -- 
+// main.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Fri May 15 23:12:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jan 27 22:20:20 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed May 04 16:54:52 2016
 // Update Count     : 199
 //
@@ -41,4 +41,5 @@
 #include "InitTweak/Mutate.h"
 #include "InitTweak/RemoveInit.h"
+#include "InitTweak/FixGlobalInit.h"
 //#include "Explain/GenProlog.h"
 //#include "Try/Visit.h"
@@ -100,5 +101,5 @@
 
 	opterr = 0;											// prevent getopt from printing error messages
-	
+
 	int c;
 	while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
@@ -172,12 +173,18 @@
 
 	try {
+		std::string fileName;
+
 		// choose to read the program from a file or stdin
 		if ( optind < argc ) {
 			input = fopen( argv[ optind ], "r" );
 			if ( ! input ) {
-				std::cout << "Error: can't open " << argv[optind] << std::endl;
+				std::cout << "Error: can't open " << argv[ optind ] << std::endl;
 				exit( 1 );
 			} // if
 			optind += 1;
+
+			// assert( optind < argc );
+			fileName = argv[ optind-1 ]; // placeholder
+			// optind += 1;
 		} else {
 			input = stdin;
@@ -187,5 +194,5 @@
 			output = new ofstream( argv[ optind ] );
 		} // if
-	
+
 		Parser::get_parser().set_debug( grammarp );
 
@@ -208,11 +215,11 @@
 					exit( 1 );
 				} // if
-		    
+
 				parse( prelude, LinkageSpec::Intrinsic );
 			} // if
 		} // if
 
-		parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );	
-  
+		parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );
+
 		if ( parsep ) {
 			Parser::get_parser().get_parseTree()->printList( std::cout );
@@ -249,6 +256,8 @@
 		OPTPRINT( "mutate" )
 		ControlStruct::mutate( translationUnit );
-		OPTPRINT( "fixNames" ) 
+		OPTPRINT( "fixNames" )
 		CodeGen::fixNames( translationUnit );
+		OPTPRINT( "fixGlobalInit" );
+		InitTweak::fixGlobalInit( translationUnit, fileName );
 		OPTPRINT( "tweak" )
 		InitTweak::tweak( translationUnit );
@@ -278,5 +287,5 @@
 		OPTPRINT( "box" )
 		GenPoly::box( translationUnit );
-		
+
 		// print tree right before code generation
 		if ( codegenp ) {
@@ -334,5 +343,5 @@
 	std::list< Declaration * > decls;
 	if ( noprotop ) {
-		filter( translationUnit.begin(), translationUnit.end(), 
+		filter( translationUnit.begin(), translationUnit.end(),
 				std::back_inserter( decls ), notPrelude );
 	} else {
