Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/CodeGen/CodeGenerator.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CodeGenerator.cc -- 
+// CodeGenerator.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:32:16 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 06 15:40:35 2016
 // Update Count     : 243
 //
@@ -75,4 +75,24 @@
 	//*** Declarations
 	void CodeGenerator::visit( FunctionDecl *functionDecl ) {
+		// generalize this
+		FunctionDecl::Attribute attr = functionDecl->get_attribute();
+		switch ( attr.type ) {
+			case FunctionDecl::Attribute::Constructor:
+				output << "__attribute__ ((constructor";
+				if ( attr.priority != FunctionDecl::Attribute::Default ) {
+					output << "(" << attr.priority << ")";
+				}
+				output << ")) ";
+				break;
+			case FunctionDecl::Attribute::Destructor:
+				output << "__attribute__ ((destructor";
+				if ( attr.priority != FunctionDecl::Attribute::Default ) {
+					output << "(" << attr.priority << ")";
+				}
+				output << ")) ";
+				break;
+			default:
+				break;
+		}
 		handleStorageClass( functionDecl );
 		if ( functionDecl->get_isInline() ) {
@@ -99,5 +119,5 @@
 		handleStorageClass( objectDecl );
 		output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
-	
+
 		if ( objectDecl->get_init() ) {
 			output << " = ";
@@ -113,5 +133,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration * > &memb = aggDecl->get_members();
 
@@ -119,12 +139,12 @@
 			output << " {" << endl;
 
-			cur_indent += CodeGenerator::tabsize; 
+			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
-				output << indent; 
+				output << indent;
 				(*i)->accept( *this );
 				output << ";" << endl;
 			}
 
-			cur_indent -= CodeGenerator::tabsize; 
+			cur_indent -= CodeGenerator::tabsize;
 
 			output << indent << "}";
@@ -141,5 +161,5 @@
 		handleAggregate( aggregateDecl );
 	}
-  
+
 	void CodeGenerator::visit( EnumDecl *aggDecl ) {
 		output << "enum ";
@@ -147,5 +167,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration* > &memb = aggDecl->get_members();
 
@@ -153,9 +173,9 @@
 			output << " {" << endl;
 
-			cur_indent += CodeGenerator::tabsize; 
+			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
 				ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
-				output << indent << mangleName( obj ); 
+				output << indent << mangleName( obj );
 				if ( obj->get_init() ) {
 					output << " = ";
@@ -165,17 +185,17 @@
 			} // for
 
-			cur_indent -= CodeGenerator::tabsize; 
+			cur_indent -= CodeGenerator::tabsize;
 
 			output << indent << "}";
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
-  
+
 	void CodeGenerator::visit( TypedefDecl *typeDecl ) {
 		output << "typedef ";
 		output << genType( typeDecl->get_base(), typeDecl->get_name() );
 	}
-  
+
 	void CodeGenerator::visit( TypeDecl *typeDecl ) {
 		// really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
@@ -217,5 +237,5 @@
 	}
 
-	void CodeGenerator::visit( Constant *constant ) { 
+	void CodeGenerator::visit( Constant *constant ) {
 		output << constant->get_value() ;
 	}
@@ -234,5 +254,5 @@
 						assert( arg != applicationExpr->get_args().end() );
 						if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
-	        
+
 							*arg = addrExpr->get_arg();
 						} else {
@@ -243,10 +263,10 @@
 						break;
 					}
-	      
+
 				  default:
 					// do nothing
 					;
 				}
-	    
+
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
@@ -257,10 +277,10 @@
 					output << "]";
 					break;
-	      
+
 				  case OT_CALL:
 					// there are no intrinsic definitions of the function call operator
 					assert( false );
 					break;
-	      
+
 				  case OT_PREFIX:
 				  case OT_PREFIXASSIGN:
@@ -271,5 +291,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -288,5 +308,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_CONSTANT:
 				  case OT_LABELADDRESS:
@@ -307,5 +327,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
 		if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
@@ -321,9 +341,9 @@
 					output << "]";
 					break;
-	      
+
 				  case OT_CALL:
 					assert( false );
 					break;
-	      
+
 				  case OT_PREFIX:
 				  case OT_PREFIXASSIGN:
@@ -335,5 +355,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -342,5 +362,5 @@
 					output << opInfo.symbol;
 					break;
-  
+
 				  case OT_INFIX:
 				  case OT_INFIXASSIGN:
@@ -352,5 +372,5 @@
 					output << ")";
 					break;
-					
+
 				  case OT_CONSTANT:
 					// there are no intrinsic definitions of 0 or 1 as functions
@@ -370,5 +390,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( NameExpr *nameExpr ) {
 		OperatorInfo opInfo;
@@ -380,5 +400,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( AddressExpr *addressExpr ) {
 		output << "(&";
@@ -409,14 +429,14 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
 		assert( false );
 	}
-  
+
 	void CodeGenerator::visit( MemberExpr *memberExpr ) {
 		memberExpr->get_aggregate()->accept( *this );
 		output << "." << mangleName( memberExpr->get_member() );
 	}
-  
+
 	void CodeGenerator::visit( VariableExpr *variableExpr ) {
 		OperatorInfo opInfo;
@@ -427,10 +447,10 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( ConstantExpr *constantExpr ) {
 		assert( constantExpr->get_constant() );
 		constantExpr->get_constant()->accept( *this );
 	}
-  
+
 	void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
 		output << "sizeof(";
@@ -469,5 +489,5 @@
 		assert( false && "OffsetPackExpr should not reach code generation" );
 	}
-  
+
 	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
 		output << "(";
@@ -481,5 +501,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
 		output << "(";
@@ -491,5 +511,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( CommaExpr *commaExpr ) {
 		output << "(";
@@ -499,7 +519,7 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
-  
+
 	void CodeGenerator::visit( TypeExpr *typeExpr ) {}
 
@@ -532,5 +552,5 @@
 			}
 		}
-		cur_indent -= CodeGenerator::tabsize; 
+		cur_indent -= CodeGenerator::tabsize;
 
 		output << indent << "}";
@@ -538,6 +558,6 @@
 
 	void CodeGenerator::visit( ExprStmt *exprStmt ) {
-		// I don't see why this check is necessary. 
-		// If this starts to cause problems then put it back in, 
+		// I don't see why this check is necessary.
+		// If this starts to cause problems then put it back in,
 		// with an explanation
 		assert( exprStmt );
@@ -589,5 +609,5 @@
 		switchStmt->get_condition()->accept( *this );
 		output << " ) ";
-		
+
 		output << "{" << std::endl;
 		cur_indent += CodeGenerator::tabsize;
@@ -609,5 +629,5 @@
 		} // if
 		output << ":\n";
-		
+
 		std::list<Statement *> sts = caseStmt->get_statements();
 
@@ -626,5 +646,5 @@
 			if ( ! branchStmt->get_target().empty() )
 				output << "goto " << branchStmt->get_target();
-			else { 
+			else {
 				if ( branchStmt->get_computedTarget() != 0 ) {
 					output << "goto *";
@@ -677,6 +697,6 @@
 
 	void CodeGenerator::visit( ForStmt *forStmt ) {
-		// initialization is always hoisted, so don't 
-		// bother doing anything with that 
+		// initialization is always hoisted, so don't
+		// bother doing anything with that
 		output << "for (;";
 
@@ -702,5 +722,5 @@
 	void CodeGenerator::visit( DeclStmt *declStmt ) {
 		declStmt->get_decl()->accept( *this );
-	
+
 		if ( doSemicolon( declStmt->get_decl() ) ) {
 			output << ";";
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
+++ src/InitTweak/FixGlobalInit.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -0,0 +1,147 @@
+//
+// 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 : Fri May 06 15:40:48 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 & name, bool inLibrary );
+
+		virtual void visit( ObjectDecl *objDecl );
+		virtual void visit( FunctionDecl *functionDecl );
+		virtual void visit( StructDecl *aggregateDecl );
+		virtual void visit( UnionDecl *aggregateDecl );
+		virtual void visit( EnumDecl *aggregateDecl );
+		virtual void visit( TraitDecl *aggregateDecl );
+		virtual void visit( TypeDecl *typeDecl );
+
+		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, bool inLibrary ) {
+		GlobalFixer fixer( name, inLibrary );
+		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 & name, bool inLibrary ) : tempNamer( "_global_init" ) {
+		initFunction = new FunctionDecl( initName( name ), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Constructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) );
+	}
+
+	void GlobalFixer::visit( ObjectDecl *objDecl ) {
+		std::list< Statement * > & statements = initFunction->get_statements()->get_kids();
+
+		if ( objDecl->get_init() == NULL ) return;
+		if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
+		// C allows you to initialize objects with constant expressions
+		// xxx - this is an optimization. Need to first resolve constructors before we decide
+		// to keep C-style initializer.
+		// 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
+	}
+
+	// only modify global variables
+	void GlobalFixer::visit( FunctionDecl *functionDecl ) {}
+	void GlobalFixer::visit( StructDecl *aggregateDecl ) {}
+	void GlobalFixer::visit( UnionDecl *aggregateDecl ) {}
+	void GlobalFixer::visit( EnumDecl *aggregateDecl ) {}
+	void GlobalFixer::visit( TraitDecl *aggregateDecl ) {}
+	void GlobalFixer::visit( TypeDecl *typeDecl ) {}
+
+} // namespace InitTweak
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/InitTweak/FixGlobalInit.h
===================================================================
--- src/InitTweak/FixGlobalInit.h	(revision af187131bf047bddfae14374ddf3536a45b617ad)
+++ src/InitTweak/FixGlobalInit.h	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -0,0 +1,42 @@
+//
+// 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 : Fri May 06 15:29:13 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.
+  /// Sets the priority of the initialization function depending on whether the initialization
+  /// function is for library code.
+  void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
+
+  /// 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 cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/InitTweak/module.mk	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -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 cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/Makefile.in	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -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/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/SynTree/Declaration.h	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Declaration.h -- 
+// Declaration.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:28:11 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 06 15:39:02 2016
 // Update Count     : 33
 //
@@ -106,5 +106,17 @@
 	typedef DeclarationWithType Parent;
   public:
-	FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn );
+	// temporary - merge this into general GCC attributes
+	struct Attribute {
+		enum Type {
+			NoAttribute, Constructor, Destructor,
+		} type;
+		enum Priority {
+			// priorities 0-100 are reserved by gcc, so it's okay to use 100 an exceptional case
+			Default = 100, High,
+		} priority;
+		Attribute(Type t = NoAttribute, Priority p = Default) : type(t), priority(p) {};
+	};
+
+	FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute = Attribute() );
 	FunctionDecl( const FunctionDecl &other );
 	virtual ~FunctionDecl();
@@ -119,4 +131,6 @@
 	std::list< std::string >& get_oldIdents() { return oldIdents; }
 	std::list< Declaration* >& get_oldDecls() { return oldDecls; }
+	Attribute get_attribute() const { return attribute; }
+	void set_attribute( Attribute newValue ) { attribute = newValue; }
 
 	virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
@@ -130,4 +144,5 @@
 	std::list< std::string > oldIdents;
 	std::list< Declaration* > oldDecls;
+	Attribute attribute;
 };
 
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/SynTree/FunctionDecl.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FunctionDecl.cc -- 
+// FunctionDecl.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jul 13 18:11:44 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 06 15:41:05 2016
 // Update Count     : 19
 //
@@ -21,6 +21,6 @@
 #include "Common/utility.h"
 
-FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn )
-		: Parent( name, sc, linkage ), type( type ), statements( statements ) {
+FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute )
+		: Parent( name, sc, linkage ), type( type ), statements( statements ), attribute( attribute ) {
 	set_isInline( isInline );
 	set_isNoreturn( isNoreturn );
@@ -32,5 +32,5 @@
 
 FunctionDecl::FunctionDecl( const FunctionDecl &other )
-	: Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
+	: Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), attribute( other.attribute ) {
 }
 
@@ -52,5 +52,5 @@
 	using std::endl;
 	using std::string;
-	
+
 	if ( get_name() != "" ) {
 		os << get_name() << ": ";
@@ -65,4 +65,17 @@
 		os << "_Noreturn ";
 	} // if
+	switch ( attribute.type ) {
+		case Attribute::Constructor:
+			os << "Global Constructor ";
+			break;
+		case Attribute::Destructor:
+			os << "Global Destructor ";
+			break;
+		default:
+			break;
+	}
+	if ( attribute.priority != Attribute::Default ) {
+		os << "with priority " << attribute.priority << " ";
+	}
 	if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
 		os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
@@ -94,5 +107,5 @@
 	using std::endl;
 	using std::string;
-	
+
 	if ( get_name() != "" ) {
 		os << get_name() << ": ";
@@ -104,4 +117,17 @@
 		os << "_Noreturn ";
 	} // if
+	switch ( attribute.type ) {
+		case Attribute::Constructor:
+			os << " Global Constructor ";
+			break;
+		case Attribute::Destructor:
+			os << " Global Destructor ";
+			break;
+		default:
+			break;
+	}
+	if ( attribute.priority != Attribute::Default ) {
+		os << "with priority " << attribute.priority << " ";
+	}
 	if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
 		os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Index: src/driver/cc1.cc
===================================================================
--- src/driver/cc1.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/driver/cc1.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -10,6 +10,6 @@
 // Created On       : Fri Aug 26 14:23:51 2005
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  4 23:29:19 2016
-// Update Count     : 74
+// Last Modified On : Thu May  5 16:04:30 2016
+// Update Count     : 77
 //
 
@@ -323,17 +323,8 @@
 		cargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
 
-		// Source file-name without suffix used to generate routine names containing external initializations for TU.
-		string filename( cpp_in );
-		string::size_type posn = filename.find_last_of( "/" );
-		if ( posn != string::npos ) {
-			filename = filename.substr( posn + 1 );
-		} // if
-		posn = filename.find_last_of( "." );
-		if ( posn != string::npos ) {
-			filename = filename.substr( 0, posn );
-		} // if
+		// Source file-name used to generate routine names containing global initializations for TU.
 		cargs[ncargs] = ( *new string( "-F" ) ).c_str();
 		ncargs += 1;
-		cargs[ncargs] = ( *new string( filename ) ).c_str();
+		cargs[ncargs] = ( *new string( string( cpp_in ) ) ).c_str();
 		ncargs += 1;
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/main.cc	(revision af187131bf047bddfae14374ddf3536a45b617ad)
@@ -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 May  4 23:32:59 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 06 15:29:42 2016
 // Update Count     : 203
 //
@@ -41,4 +41,5 @@
 #include "InitTweak/Mutate.h"
 #include "InitTweak/RemoveInit.h"
+#include "InitTweak/FixGlobalInit.h"
 //#include "Explain/GenProlog.h"
 //#include "Try/Visit.h"
@@ -98,8 +99,8 @@
 	int long_index;
 	std::list< Declaration * > translationUnit;
-	const char *filename = NULL;;
+	const char *filename = NULL;
 
 	opterr = 0;											// prevent getopt from printing error messages
-	
+
 	int c;
 	while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) {
@@ -180,7 +181,11 @@
 			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
+			// if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to)
+			if ( filename == NULL ) filename = argv[ optind ];
+			// prelude filename comes in differently
+			if ( libcfap ) filename = "prelude.cf";
 			optind += 1;
 		} else {
@@ -191,5 +196,5 @@
 			output = new ofstream( argv[ optind ] );
 		} // if
-	
+
 		Parser::get_parser().set_debug( grammarp );
 
@@ -212,11 +217,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 );
@@ -253,6 +258,8 @@
 		OPTPRINT( "mutate" )
 		ControlStruct::mutate( translationUnit );
-		OPTPRINT( "fixNames" ) 
+		OPTPRINT( "fixNames" )
 		CodeGen::fixNames( translationUnit );
+		OPTPRINT( "fixGlobalInit" );
+		InitTweak::fixGlobalInit( translationUnit, filename, libcfap || treep );
 		OPTPRINT( "tweak" )
 		InitTweak::tweak( translationUnit );
@@ -282,5 +289,5 @@
 		OPTPRINT( "box" )
 		GenPoly::box( translationUnit );
-		
+
 		// print tree right before code generation
 		if ( codegenp ) {
@@ -338,5 +345,5 @@
 	std::list< Declaration * > decls;
 	if ( noprotop ) {
-		filter( translationUnit.begin(), translationUnit.end(), 
+		filter( translationUnit.begin(), translationUnit.end(),
 				std::back_inserter( decls ), notPrelude );
 	} else {
