Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/AST/Print.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -1579,11 +1579,11 @@
 		preprint( node );
 		os << "enum attr ";
-        if ( node->attr == ast::EnumAttribute::Label ) {
-            os << "Label ";
-        } else if ( node->attr == ast::EnumAttribute::Value ) {
-            os << "Value ";
-        } else {
-            os << "Posn ";
-        }
+		if ( node->attr == ast::EnumAttribute::Label ) {
+			os << "Label ";
+		} else if ( node->attr == ast::EnumAttribute::Value ) {
+			os << "Value ";
+		} else {
+			os << "Posn ";
+		}
 		(*(node->instance)).accept( *this );
 		return node;
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/AST/Type.hpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -31,5 +31,5 @@
 // Must be included in *all* AST classes; should be #undef'd at the end of the file
 #define MUTATE_FRIEND \
-    template<typename node_t> friend node_t * mutate(const node_t * node); \
+	template<typename node_t> friend node_t * mutate(const node_t * node); \
 	template<typename node_t> friend node_t * shallowCopy(const node_t * node);
 
@@ -322,12 +322,12 @@
 public:
 	readonly<EnumInstType> instance;
-    EnumAttribute attr;
+	EnumAttribute attr;
 	const Type * accept( Visitor & v ) const override { return v.visit( this ); }
 	EnumAttrType( const EnumInstType * instance, EnumAttribute attr = EnumAttribute::Posn )
 		: instance(instance), attr(attr) {}
-	
-    bool match( const ast::EnumAttrType * other) const {
-        return instance->base->name == other->instance->base->name && attr == other->attr;
-    }
+
+	bool match( const ast::EnumAttrType * other) const {
+		return instance->base->name == other->instance->base->name && attr == other->attr;
+	}
 private:
 	EnumAttrType * clone() const override { return new EnumAttrType{ *this }; }
Index: src/BasicTypes-gen.cc
===================================================================
--- src/BasicTypes-gen.cc	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/BasicTypes-gen.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -415,5 +415,5 @@
 	code << "\t" << BYMK << endl;
 	code << "\t#define BT ast::BasicKind::" << endl;
-	code << "\tstatic const BT Kind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor" << endl
+	code << "\tstatic const ast::BasicKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor" << endl
 	     << "\t\t/*\t\t ";
 	for ( int r = 0; r < NUMBER_OF_BASIC_TYPES; r += 1 ) { // titles
Index: src/Common/PersistentMap.h
===================================================================
--- src/Common/PersistentMap.h	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Common/PersistentMap.h	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -23,11 +23,11 @@
 #include <utility>        // for forward, move
 
-/// Wraps a hash table in a persistent data structure, using a technique based 
-/// on the persistent array in Conchon & Filliatre "A Persistent Union-Find 
+/// Wraps a hash table in a persistent data structure, using a technique based
+/// on the persistent array in Conchon & Filliatre "A Persistent Union-Find
 /// Data Structure"
 
 template<typename Key, typename Val,
-         typename Hash = std::hash<Key>, typename Eq = std::equal_to<Key>>
-class PersistentMap 
+		typename Hash = std::hash<Key>, typename Eq = std::equal_to<Key>>
+class PersistentMap
 	: public std::enable_shared_from_this<PersistentMap<Key, Val, Hash, Eq>> {
 public:
@@ -38,5 +38,5 @@
 
 	/// Types of version nodes
-	enum Mode { 
+	enum Mode {
 		BASE,  ///< Root node of version tree
 		REM,   ///< Key removal node
@@ -63,5 +63,5 @@
 		Ptr base;  ///< Modified map
 		Key key;   ///< Key removed
-		
+
 		template<typename P, typename K>
 		Rem(P&& p, K&& k) : base(std::forward<P>(p)), key(std::forward<K>(k)) {}
@@ -155,5 +155,5 @@
 				auto it = base_map.find( self.key );
 
-				base->template init<Ins>( 
+				base->template init<Ins>(
 						mut_this->shared_from_this(), std::move(self.key), std::move(it->second) );
 				base->mode = INS;
@@ -175,5 +175,5 @@
 				auto it = base_map.find( self.key );
 
-				base->template init<Ins>( 
+				base->template init<Ins>(
 						mut_this->shared_from_this(), std::move(self.key), std::move(it->second) );
 				base->mode = UPD;
@@ -267,5 +267,5 @@
 	Ptr erase(const Key& k) {
 		reroot();
-		
+
 		// exit early if key does not exist in map
 		if ( ! as<Base>().count( k ) ) return this->shared_from_this();
Index: src/Common/VectorMap.h
===================================================================
--- src/Common/VectorMap.h	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Common/VectorMap.h	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -36,13 +36,11 @@
 	typedef const value_type* pointer;
 	typedef const const_value_type* const_pointer;
-	
-	class iterator : public std::iterator< std::random_access_iterator_tag,
-	                                       value_type,
-										   difference_type,
-										   pointer,
-										   reference > {
-	friend class VectorMap;
-	friend class const_iterator;
-	
+
+	class iterator : public std::iterator<
+			std::random_access_iterator_tag,
+			value_type, difference_type, pointer, reference > {
+		friend class VectorMap;
+		friend class const_iterator;
+
 		value_type data;
 
@@ -99,5 +97,5 @@
 			return data.first == o.data.first && &data.second == &o.data.second;
 		}
-		
+
 		bool operator!= (const iterator& that) const { return !(*this == that); }
 
@@ -111,10 +109,8 @@
 	};
 
-	class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
-	                                             const_value_type,
-												  difference_type,
-												  const_pointer,
-												  const_reference  > {
-	friend class VectorMap;
+	class const_iterator : public std::iterator<
+			std::bidirectional_iterator_tag,
+			const_value_type, difference_type, const_pointer, const_reference > {
+		friend class VectorMap;
 		const_value_type data;
 
@@ -181,5 +177,5 @@
 			return data.first == o.data.first && &data.second == &o.data.second;
 		}
-		
+
 		bool operator!= (const const_iterator& that) const { return !(*this == that); }
 
@@ -233,12 +229,14 @@
 
 template<typename T>
-typename VectorMap<T>::iterator operator+ (typename VectorMap<T>::difference_type i, 
-                                           const typename VectorMap<T>::iterator& it) {
+typename VectorMap<T>::iterator operator+(
+		typename VectorMap<T>::difference_type i,
+		const typename VectorMap<T>::iterator& it) {
 	return it + i;
 }
 
 template<typename T>
-typename VectorMap<T>::const_iterator operator+ (typename VectorMap<T>::difference_type i, 
-                                                 const typename VectorMap<T>::const_iterator& it) {
+typename VectorMap<T>::const_iterator operator+(
+		typename VectorMap<T>::difference_type i,
+		const typename VectorMap<T>::const_iterator& it) {
 	return it + i;
 }
Index: src/Concurrency/Actors.cpp
===================================================================
--- src/Concurrency/Actors.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Concurrency/Actors.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -28,68 +28,68 @@
 
 struct CollectactorStructDecls : public ast::WithGuards {
-    unordered_set<const StructDecl *> & actorStructDecls;
-    unordered_set<const StructDecl *>  & messageStructDecls;
-    const StructDecl ** requestDecl;
-    const EnumDecl ** allocationDecl;
-    const StructDecl ** actorDecl;
-    const StructDecl ** msgDecl;
-    StructDecl * parentDecl;
-    bool insideStruct = false;
-    bool namedDecl = false;
-
-    // finds and sets a ptr to the allocation enum, which is needed in the next pass
-    void previsit( const EnumDecl * decl ) {
-        if( decl->name == "allocation" ) *allocationDecl = decl;
-    }
-
-    // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
-    void previsit( const StructDecl * decl ) {
-        if ( !decl->body ) return;
-        if ( decl->name == "actor" ) {
-            actorStructDecls.insert( decl ); // skip inserting fwd decl
-            *actorDecl = decl;
-        } else if( decl->name == "message" ) {
-            messageStructDecls.insert( decl ); // skip inserting fwd decl
-            *msgDecl = decl;
-        } else if( decl->name == "request" ) *requestDecl = decl;
-        else {
-            GuardValue(insideStruct);
-            insideStruct = true;
-            parentDecl = mutate( decl );
-        }
-	}
-
-    // this catches structs of the form:
-    //     struct dummy_actor { actor a; };
-    // since they should be:
-    //     struct dummy_actor { inline actor; };
-    void previsit ( const ObjectDecl * decl ) {
-        if ( insideStruct && ! decl->name.empty() ) {
-            GuardValue(namedDecl);
-            namedDecl = true;
-        }
-    }
-
-    // this collects the derived actor and message struct decl ptrs
-    void postvisit( const StructInstType * node ) {
-        if ( ! *actorDecl || ! *msgDecl ) return;
-        if ( insideStruct && !namedDecl ) {
-            auto actorIter = actorStructDecls.find( node->aggr() );    
-            if ( actorIter != actorStructDecls.end() ) {
-                actorStructDecls.insert( parentDecl );
-                return;
-            }
-            auto messageIter = messageStructDecls.find( node->aggr() );
-            if ( messageIter != messageStructDecls.end() ) {
-                messageStructDecls.insert( parentDecl );
-            }
-        }
+	unordered_set<const StructDecl *> & actorStructDecls;
+	unordered_set<const StructDecl *>  & messageStructDecls;
+	const StructDecl ** requestDecl;
+	const EnumDecl ** allocationDecl;
+	const StructDecl ** actorDecl;
+	const StructDecl ** msgDecl;
+	StructDecl * parentDecl;
+	bool insideStruct = false;
+	bool namedDecl = false;
+
+	// finds and sets a ptr to the allocation enum, which is needed in the next pass
+	void previsit( const EnumDecl * decl ) {
+		if( decl->name == "allocation" ) *allocationDecl = decl;
+	}
+
+	// finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
+	void previsit( const StructDecl * decl ) {
+		if ( !decl->body ) return;
+		if ( decl->name == "actor" ) {
+			actorStructDecls.insert( decl ); // skip inserting fwd decl
+			*actorDecl = decl;
+		} else if( decl->name == "message" ) {
+			messageStructDecls.insert( decl ); // skip inserting fwd decl
+			*msgDecl = decl;
+		} else if( decl->name == "request" ) *requestDecl = decl;
+		else {
+			GuardValue(insideStruct);
+			insideStruct = true;
+			parentDecl = mutate( decl );
+		}
+	}
+
+	// this catches structs of the form:
+	//     struct dummy_actor { actor a; };
+	// since they should be:
+	//     struct dummy_actor { inline actor; };
+	void previsit ( const ObjectDecl * decl ) {
+		if ( insideStruct && ! decl->name.empty() ) {
+			GuardValue(namedDecl);
+			namedDecl = true;
+		}
+	}
+
+	// this collects the derived actor and message struct decl ptrs
+	void postvisit( const StructInstType * node ) {
+		if ( ! *actorDecl || ! *msgDecl ) return;
+		if ( insideStruct && !namedDecl ) {
+			auto actorIter = actorStructDecls.find( node->aggr() );
+			if ( actorIter != actorStructDecls.end() ) {
+				actorStructDecls.insert( parentDecl );
+				return;
+			}
+			auto messageIter = messageStructDecls.find( node->aggr() );
+			if ( messageIter != messageStructDecls.end() ) {
+				messageStructDecls.insert( parentDecl );
+			}
+		}
 	}
 
   public:
-    CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
-        const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 
-        : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), 
-        allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {}
+	CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
+		const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl )
+		: actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ),
+		allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {}
 };
 
@@ -97,353 +97,353 @@
 class FwdDeclTable {
 
-    // tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible
-    struct FwdDeclData { 
-        const StructDecl * actorDecl;
-        const StructDecl * msgDecl;
-        FunctionDecl * fwdDecl;
-        bool actorFound;
-        bool msgFound;
-
-        bool readyToInsert() { return actorFound && msgFound; }
-        bool foundActor() { actorFound = true; return readyToInsert(); }
-        bool foundMsg() { msgFound = true; return readyToInsert(); }
-
-        FwdDeclData( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) :
-            actorDecl(actorDecl), msgDecl(msgDecl), fwdDecl(fwdDecl), actorFound(false), msgFound(false) {}
-    };
-
-    // map indexed by actor struct ptr
-    // value is map of all FwdDeclData that contains said actor struct ptr
-    // inner map is indexed by the message struct ptr of FwdDeclData
-    unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> actorMap;
-
-    // this map is the same except the outer map is indexed by message ptr and the inner is indexed by actor ptr
-    unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> msgMap;
-
-    void insert( const StructDecl * decl, const StructDecl * otherDecl, unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map, FwdDeclData * data ) {
-        auto iter = map.find( decl );
-        if ( iter != map.end() ) { // if decl exists in map append data to existing inner map
-            iter->second.emplace( make_pair( otherDecl, data ) );
-        } else { // else create inner map for key
-            map.emplace( make_pair( decl, unordered_map<const StructDecl *, FwdDeclData *>( { make_pair( otherDecl, data ) } ) ) );
-        }
-    }
+	// tracks which decls we have seen so that we can hoist the FunctionDecl to the highest point possible
+	struct FwdDeclData {
+		const StructDecl * actorDecl;
+		const StructDecl * msgDecl;
+		FunctionDecl * fwdDecl;
+		bool actorFound;
+		bool msgFound;
+
+		bool readyToInsert() { return actorFound && msgFound; }
+		bool foundActor() { actorFound = true; return readyToInsert(); }
+		bool foundMsg() { msgFound = true; return readyToInsert(); }
+
+		FwdDeclData( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) :
+			actorDecl(actorDecl), msgDecl(msgDecl), fwdDecl(fwdDecl), actorFound(false), msgFound(false) {}
+	};
+
+	// map indexed by actor struct ptr
+	// value is map of all FwdDeclData that contains said actor struct ptr
+	// inner map is indexed by the message struct ptr of FwdDeclData
+	unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> actorMap;
+
+	// this map is the same except the outer map is indexed by message ptr and the inner is indexed by actor ptr
+	unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> msgMap;
+
+	void insert( const StructDecl * decl, const StructDecl * otherDecl, unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map, FwdDeclData * data ) {
+		auto iter = map.find( decl );
+		if ( iter != map.end() ) { // if decl exists in map append data to existing inner map
+			iter->second.emplace( make_pair( otherDecl, data ) );
+		} else { // else create inner map for key
+			map.emplace( make_pair( decl, unordered_map<const StructDecl *, FwdDeclData *>( { make_pair( otherDecl, data ) } ) ) );
+		}
+	}
 
   public:
-    // insert decl into table so that we can fwd declare it later (average cost: O(1))
-    void insertDecl( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) {
-        FwdDeclData * declToInsert = new FwdDeclData( actorDecl, msgDecl, fwdDecl );
-        insert( actorDecl, msgDecl, actorMap, declToInsert );
-        insert( msgDecl, actorDecl, msgMap, declToInsert );
-    }
-
-    // returns list of decls to insert after current struct decl
-    // Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines
-    list<FunctionDecl *> updateDecl( const StructDecl * decl, bool isMsg ) {
-        unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map = isMsg ? msgMap : actorMap;
-        unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & otherMap =  isMsg ? actorMap : msgMap;
-        auto iter = map.find( decl );
-        list<FunctionDecl *> toInsertAfter; // this is populated with decls that are ready to insert
-        if ( iter == map.end() ) return toInsertAfter;
-        
-        // iterate over inner map
-        unordered_map<const StructDecl *, FwdDeclData *> & currInnerMap = iter->second;
-        for ( auto innerIter = currInnerMap.begin(); innerIter != currInnerMap.end(); ) {
-            FwdDeclData * currentDatum = innerIter->second;
-            bool readyToInsert = isMsg ? currentDatum->foundMsg() : currentDatum->foundActor();
-            if ( ! readyToInsert ) { ++innerIter; continue; }
-            
-            // readyToInsert is true so we are good to insert the forward decl of the message fn
-            toInsertAfter.push_back( currentDatum->fwdDecl );
-
-            // need to remove from other map before deleting
-            // find inner map in other map ( other map is actor map if original is msg map and vice versa )
-            const StructDecl * otherDecl = isMsg ? currentDatum->actorDecl : currentDatum->msgDecl;
-            auto otherMapIter = otherMap.find( otherDecl );
-
-            unordered_map<const StructDecl *, FwdDeclData *> & otherInnerMap = otherMapIter->second;
-
-            // find the FwdDeclData we need to remove in the other inner map
-            auto otherInnerIter = otherInnerMap.find( decl );
-
-            // remove references to deleted FwdDeclData from current inner map
-            innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed
-
-            // remove references to deleted FwdDeclData from other inner map
-            otherInnerMap.erase( otherInnerIter );
-            
-            // if other inner map is now empty, remove key from other outer map
-            if ( otherInnerMap.empty() )
-                otherMap.erase( otherDecl );
-
-            // now we are safe to delete the FwdDeclData since we are done with it
-            // and we have removed all references to it from our data structures
-            delete currentDatum;
-        }
-
-        // if current inner map is now empty, remove key from outer map.
-        // Have to do this after iterating for safety
-        if ( currInnerMap.empty() )
-            map.erase( decl );
-
-        return toInsertAfter;
-    }
+	// insert decl into table so that we can fwd declare it later (average cost: O(1))
+	void insertDecl( const StructDecl * actorDecl, const StructDecl * msgDecl, FunctionDecl * fwdDecl ) {
+		FwdDeclData * declToInsert = new FwdDeclData( actorDecl, msgDecl, fwdDecl );
+		insert( actorDecl, msgDecl, actorMap, declToInsert );
+		insert( msgDecl, actorDecl, msgMap, declToInsert );
+	}
+
+	// returns list of decls to insert after current struct decl
+	// Over the entire pass the runtime of this routine is O(r) where r is the # of receive routines
+	list<FunctionDecl *> updateDecl( const StructDecl * decl, bool isMsg ) {
+		unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & map = isMsg ? msgMap : actorMap;
+		unordered_map<const StructDecl *, unordered_map<const StructDecl *, FwdDeclData *>> & otherMap =  isMsg ? actorMap : msgMap;
+		auto iter = map.find( decl );
+		list<FunctionDecl *> toInsertAfter; // this is populated with decls that are ready to insert
+		if ( iter == map.end() ) return toInsertAfter;
+
+		// iterate over inner map
+		unordered_map<const StructDecl *, FwdDeclData *> & currInnerMap = iter->second;
+		for ( auto innerIter = currInnerMap.begin(); innerIter != currInnerMap.end(); ) {
+			FwdDeclData * currentDatum = innerIter->second;
+			bool readyToInsert = isMsg ? currentDatum->foundMsg() : currentDatum->foundActor();
+			if ( ! readyToInsert ) { ++innerIter; continue; }
+
+			// readyToInsert is true so we are good to insert the forward decl of the message fn
+			toInsertAfter.push_back( currentDatum->fwdDecl );
+
+			// need to remove from other map before deleting
+			// find inner map in other map ( other map is actor map if original is msg map and vice versa )
+			const StructDecl * otherDecl = isMsg ? currentDatum->actorDecl : currentDatum->msgDecl;
+			auto otherMapIter = otherMap.find( otherDecl );
+
+			unordered_map<const StructDecl *, FwdDeclData *> & otherInnerMap = otherMapIter->second;
+
+			// find the FwdDeclData we need to remove in the other inner map
+			auto otherInnerIter = otherInnerMap.find( decl );
+
+			// remove references to deleted FwdDeclData from current inner map
+			innerIter = currInnerMap.erase( innerIter ); // this does the increment so no explicit inc needed
+
+			// remove references to deleted FwdDeclData from other inner map
+			otherInnerMap.erase( otherInnerIter );
+
+			// if other inner map is now empty, remove key from other outer map
+			if ( otherInnerMap.empty() )
+				otherMap.erase( otherDecl );
+
+			// now we are safe to delete the FwdDeclData since we are done with it
+			// and we have removed all references to it from our data structures
+			delete currentDatum;
+		}
+
+		// if current inner map is now empty, remove key from outer map.
+		// Have to do this after iterating for safety
+		if ( currInnerMap.empty() )
+			map.erase( decl );
+
+		return toInsertAfter;
+	}
 };
 
 // generates the definitions of send operators for actors
-// collects data needed for next pass that does the circular defn resolution 
+// collects data needed for next pass that does the circular defn resolution
 //     for message send operators (via table above)
 struct GenFuncsCreateTables : public ast::WithDeclsToAdd<> {
-    unordered_set<const StructDecl *> & actorStructDecls;
-    unordered_set<const StructDecl *>  & messageStructDecls;
-    const StructDecl ** requestDecl;
-    const EnumDecl ** allocationDecl;
-    const StructDecl ** actorDecl;
-    const StructDecl ** msgDecl;
-    FwdDeclTable & forwardDecls;
-
-    // generates the operator for actor message sends
+	unordered_set<const StructDecl *> & actorStructDecls;
+	unordered_set<const StructDecl *>  & messageStructDecls;
+	const StructDecl ** requestDecl;
+	const EnumDecl ** allocationDecl;
+	const StructDecl ** actorDecl;
+	const StructDecl ** msgDecl;
+	FwdDeclTable & forwardDecls;
+
+	// generates the operator for actor message sends
 	void postvisit( const FunctionDecl * decl ) {
-        // return if not of the form receive( param1, param2 ) or if it is a forward decl
-        if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
-
-        // the params should be references
-        const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
-        const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());
-        if ( !derivedActorRef || !derivedMsgRef ) return;
-
-        // the references should be to struct instances
-        const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get());
-        const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());
-        if ( !arg1InstType || !arg2InstType ) return;
-
-        // If the struct instances are derived actor and message types then generate the message send routine
-        auto actorIter = actorStructDecls.find( arg1InstType->aggr() );
-        auto messageIter = messageStructDecls.find( arg2InstType->aggr() );
-        if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) {
-            //////////////////////////////////////////////////////////////////////
-            // The following generates this wrapper for all receive(derived_actor &, derived_msg &) functions
-            /* base_actor and base_msg are output params
-            static inline allocation __CFA_receive_wrap( derived_actor & receiver, derived_msg & msg, actor ** base_actor, message ** base_msg ) {
-                base_actor = &receiver;
-                base_msg = &msg;
-                return receive( receiver, msg );
-            }
-            */
-            CompoundStmt * wrapBody = new CompoundStmt( decl->location );
-
-            // generates: base_actor = &receiver;
-            wrapBody->push_back( new ExprStmt( decl->location,
-                UntypedExpr::createAssign( decl->location, 
-                    UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "base_actor" ) ),
-                    new AddressExpr( decl->location, new NameExpr( decl->location, "receiver" ) )
-                )
-            ));
-
-            // generates: base_msg = &msg;
-            wrapBody->push_back( new ExprStmt( decl->location,
-                UntypedExpr::createAssign( decl->location, 
-                    UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "base_msg" ) ),
-                    new AddressExpr( decl->location, new NameExpr( decl->location, "msg" ) )
-                )
-            ));
-
-            // generates: return receive( receiver, msg );
-            wrapBody->push_back( new ReturnStmt( decl->location,
-                new UntypedExpr ( decl->location,
-                    new NameExpr( decl->location, "receive" ),
-                    {
-                        new NameExpr( decl->location, "receiver" ),
-                        new NameExpr( decl->location, "msg" )
-                    }
-                )
-            ));
-
-            // create receive wrapper to extract base message and actor pointer
-            // put it all together into the complete function decl from above
-            FunctionDecl * receiveWrapper = new FunctionDecl(
-                decl->location,
-                "__CFA_receive_wrap",
-                {
-                    new ObjectDecl(
-                        decl->location,
-                        "receiver",
-                        ast::deepCopy( derivedActorRef )
-                    ),
-                    new ObjectDecl(
-                        decl->location,
-                        "msg",
-                        ast::deepCopy( derivedMsgRef )
-                    ),
-                    new ObjectDecl(
-                        decl->location,
-                        "base_actor",
-                        new PointerType( new PointerType( new StructInstType( *actorDecl ) ) )
-                    ),
-                    new ObjectDecl(
-                        decl->location,
-                        "base_msg",
-                        new PointerType( new PointerType( new StructInstType( *msgDecl ) ) )
-                    )
-                },                      // params
-                {
-                    new ObjectDecl(
-                        decl->location,
-                        "__CFA_receive_wrap_ret",
-                        new EnumInstType( *allocationDecl )
-                    )
-                },
-                wrapBody,               // body
-                { Storage::Static },    // storage
-                Linkage::Cforall,       // linkage
-                {},                     // attributes
-                { Function::Inline }
-            );
-
-            declsToAddAfter.push_back( receiveWrapper );
-
-            //////////////////////////////////////////////////////////////////////
-            // The following generates this send message operator routine for all receive(derived_actor &, derived_msg &) functions
-            /*
-                static inline derived_actor & ?|?( derived_actor & receiver, derived_msg & msg ) {
-                    request new_req;
-                    allocation (*my_work_fn)( derived_actor &, derived_msg & ) = receive;
-                    __receive_fn fn = (__receive_fn)my_work_fn;
-                    new_req{ &receiver, &msg, fn };
-                    send( receiver, new_req );
-                    return receiver;
-                }
-            */ 
-            CompoundStmt * sendBody = new CompoundStmt( decl->location );
-
-            // Generates: request new_req;
-            sendBody->push_back( new DeclStmt(
-                decl->location,
-                new ObjectDecl(
-                    decl->location,
-                    "new_req",
-                    new StructInstType( *requestDecl )
-                )
-            ));
-            
-            // Function type is: allocation (*)( derived_actor &, derived_msg &, actor **, message ** )
-            FunctionType * derivedReceive = new FunctionType();
-            derivedReceive->params.push_back( ast::deepCopy( derivedActorRef ) );
-            derivedReceive->params.push_back( ast::deepCopy( derivedMsgRef ) );
-            derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
-            derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
-            derivedReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
-
-            // Generates: allocation (*my_work_fn)( derived_actor &, derived_msg &, actor **, message ** ) = receive;
-            sendBody->push_back( new DeclStmt(
-                decl->location,
-                new ObjectDecl(
-                    decl->location,
-                    "my_work_fn",
-                    new PointerType( derivedReceive ),
-                    new SingleInit( decl->location, new NameExpr( decl->location, "__CFA_receive_wrap" ) )
-                )
-            ));
-
-            // Function type is: allocation (*)( actor &, message & )
-            FunctionType * genericReceive = new FunctionType();
-            genericReceive->params.push_back( new ReferenceType( new StructInstType( *actorDecl ) ) );
-            genericReceive->params.push_back( new ReferenceType( new StructInstType( *msgDecl ) ) );
-            genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
-            genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
-            genericReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
-
-            // Generates: allocation (*fn)( actor &, message & ) = (allocation (*)( actor &, message & ))my_work_fn;
-            // More readable synonymous code: 
-            //     typedef allocation (*__receive_fn)(actor &, message &);
-            //     __receive_fn fn = (__receive_fn)my_work_fn;
-            sendBody->push_back( new DeclStmt(
-                decl->location,
-                new ObjectDecl(
-                    decl->location,
-                    "fn",
-                    new PointerType( genericReceive ),
-                    new SingleInit( decl->location, 
-                        new CastExpr( decl->location, new NameExpr( decl->location, "my_work_fn" ), new PointerType( genericReceive ), ExplicitCast )
-                    )
-                )
-            ));
-
-            // Generates: new_req{ (actor *)&receiver, (message *)&msg, fn };
-            sendBody->push_back( new ExprStmt(
-                decl->location,
+		// return if not of the form receive( param1, param2 ) or if it is a forward decl
+		if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
+
+		// the params should be references
+		const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
+		const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());
+		if ( !derivedActorRef || !derivedMsgRef ) return;
+
+		// the references should be to struct instances
+		const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get());
+		const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());
+		if ( !arg1InstType || !arg2InstType ) return;
+
+		// If the struct instances are derived actor and message types then generate the message send routine
+		auto actorIter = actorStructDecls.find( arg1InstType->aggr() );
+		auto messageIter = messageStructDecls.find( arg2InstType->aggr() );
+		if ( actorIter != actorStructDecls.end() && messageIter != messageStructDecls.end() ) {
+			//////////////////////////////////////////////////////////////////////
+			// The following generates this wrapper for all receive(derived_actor &, derived_msg &) functions
+			/* base_actor and base_msg are output params
+			static inline allocation __CFA_receive_wrap( derived_actor & receiver, derived_msg & msg, actor ** base_actor, message ** base_msg ) {
+				base_actor = &receiver;
+				base_msg = &msg;
+				return receive( receiver, msg );
+			}
+			*/
+			CompoundStmt * wrapBody = new CompoundStmt( decl->location );
+
+			// generates: base_actor = &receiver;
+			wrapBody->push_back( new ExprStmt( decl->location,
+				UntypedExpr::createAssign( decl->location,
+					UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "base_actor" ) ),
+					new AddressExpr( decl->location, new NameExpr( decl->location, "receiver" ) )
+				)
+			));
+
+			// generates: base_msg = &msg;
+			wrapBody->push_back( new ExprStmt( decl->location,
+				UntypedExpr::createAssign( decl->location,
+					UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "base_msg" ) ),
+					new AddressExpr( decl->location, new NameExpr( decl->location, "msg" ) )
+				)
+			));
+
+			// generates: return receive( receiver, msg );
+			wrapBody->push_back( new ReturnStmt( decl->location,
+				new UntypedExpr ( decl->location,
+					new NameExpr( decl->location, "receive" ),
+					{
+						new NameExpr( decl->location, "receiver" ),
+						new NameExpr( decl->location, "msg" )
+					}
+				)
+			));
+
+			// create receive wrapper to extract base message and actor pointer
+			// put it all together into the complete function decl from above
+			FunctionDecl * receiveWrapper = new FunctionDecl(
+				decl->location,
+				"__CFA_receive_wrap",
+				{
+					new ObjectDecl(
+						decl->location,
+						"receiver",
+						ast::deepCopy( derivedActorRef )
+					),
+					new ObjectDecl(
+						decl->location,
+						"msg",
+						ast::deepCopy( derivedMsgRef )
+					),
+					new ObjectDecl(
+						decl->location,
+						"base_actor",
+						new PointerType( new PointerType( new StructInstType( *actorDecl ) ) )
+					),
+					new ObjectDecl(
+						decl->location,
+						"base_msg",
+						new PointerType( new PointerType( new StructInstType( *msgDecl ) ) )
+					)
+				},                      // params
+				{
+					new ObjectDecl(
+						decl->location,
+						"__CFA_receive_wrap_ret",
+						new EnumInstType( *allocationDecl )
+					)
+				},
+				wrapBody,               // body
+				{ Storage::Static },    // storage
+				Linkage::Cforall,       // linkage
+				{},                     // attributes
+				{ Function::Inline }
+			);
+
+			declsToAddAfter.push_back( receiveWrapper );
+
+			//////////////////////////////////////////////////////////////////////
+			// The following generates this send message operator routine for all receive(derived_actor &, derived_msg &) functions
+			/*
+				static inline derived_actor & ?|?( derived_actor & receiver, derived_msg & msg ) {
+					request new_req;
+					allocation (*my_work_fn)( derived_actor &, derived_msg & ) = receive;
+					__receive_fn fn = (__receive_fn)my_work_fn;
+					new_req{ &receiver, &msg, fn };
+					send( receiver, new_req );
+					return receiver;
+				}
+			*/
+			CompoundStmt * sendBody = new CompoundStmt( decl->location );
+
+			// Generates: request new_req;
+			sendBody->push_back( new DeclStmt(
+				decl->location,
+				new ObjectDecl(
+					decl->location,
+					"new_req",
+					new StructInstType( *requestDecl )
+				)
+			));
+
+			// Function type is: allocation (*)( derived_actor &, derived_msg &, actor **, message ** )
+			FunctionType * derivedReceive = new FunctionType();
+			derivedReceive->params.push_back( ast::deepCopy( derivedActorRef ) );
+			derivedReceive->params.push_back( ast::deepCopy( derivedMsgRef ) );
+			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
+			derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
+			derivedReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
+
+			// Generates: allocation (*my_work_fn)( derived_actor &, derived_msg &, actor **, message ** ) = receive;
+			sendBody->push_back( new DeclStmt(
+				decl->location,
+				new ObjectDecl(
+					decl->location,
+					"my_work_fn",
+					new PointerType( derivedReceive ),
+					new SingleInit( decl->location, new NameExpr( decl->location, "__CFA_receive_wrap" ) )
+				)
+			));
+
+			// Function type is: allocation (*)( actor &, message & )
+			FunctionType * genericReceive = new FunctionType();
+			genericReceive->params.push_back( new ReferenceType( new StructInstType( *actorDecl ) ) );
+			genericReceive->params.push_back( new ReferenceType( new StructInstType( *msgDecl ) ) );
+			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );
+			genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );
+			genericReceive->returns.push_back( new EnumInstType( *allocationDecl ) );
+
+			// Generates: allocation (*fn)( actor &, message & ) = (allocation (*)( actor &, message & ))my_work_fn;
+			// More readable synonymous code:
+			//     typedef allocation (*__receive_fn)(actor &, message &);
+			//     __receive_fn fn = (__receive_fn)my_work_fn;
+			sendBody->push_back( new DeclStmt(
+				decl->location,
+				new ObjectDecl(
+					decl->location,
+					"fn",
+					new PointerType( genericReceive ),
+					new SingleInit( decl->location,
+						new CastExpr( decl->location, new NameExpr( decl->location, "my_work_fn" ), new PointerType( genericReceive ), ExplicitCast )
+					)
+				)
+			));
+
+			// Generates: new_req{ (actor *)&receiver, (message *)&msg, fn };
+			sendBody->push_back( new ExprStmt(
+				decl->location,
 				new UntypedExpr (
-                    decl->location, 
+					decl->location,
 					new NameExpr( decl->location, "?{}" ),
 					{
 						new NameExpr( decl->location, "new_req" ),
-                        new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( *actorDecl ) ), ExplicitCast ),
-                        new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( *msgDecl ) ), ExplicitCast ),
-                        new NameExpr( decl->location, "fn" )
+						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( *actorDecl ) ), ExplicitCast ),
+						new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( *msgDecl ) ), ExplicitCast ),
+						new NameExpr( decl->location, "fn" )
 					}
 				)
 			));
 
-            // Generates: send( receiver, new_req );
-            sendBody->push_back( new ExprStmt(
-                decl->location,
+			// Generates: send( receiver, new_req );
+			sendBody->push_back( new ExprStmt(
+				decl->location,
 				new UntypedExpr (
-                    decl->location,
+					decl->location,
 					new NameExpr( decl->location, "send" ),
 					{
 						{
-                            new NameExpr( decl->location, "receiver" ),
-                            new NameExpr( decl->location, "new_req" )
-                        }
+							new NameExpr( decl->location, "receiver" ),
+							new NameExpr( decl->location, "new_req" )
+						}
 					}
 				)
 			));
 
-            // Generates: return receiver;
-            sendBody->push_back( new ReturnStmt( decl->location, new NameExpr( decl->location, "receiver" ) ) );
-
-            // put it all together into the complete function decl from above
-            FunctionDecl * sendOperatorFunction = new FunctionDecl(
-                decl->location,
-                "?|?",
-                {
-                    new ObjectDecl(
-                        decl->location,
-                        "receiver",
-                        ast::deepCopy( derivedActorRef )
-                    ),
-                    new ObjectDecl(
-                        decl->location,
-                        "msg",
-                        ast::deepCopy( derivedMsgRef )
-                    )
-                },                      // params
-                {
-                    new ObjectDecl(
-                        decl->location,
-                        "receiver_ret",
-                        ast::deepCopy( derivedActorRef )
-                    )
-                },
-                nullptr,               // body
-                { Storage::Static },    // storage
-                Linkage::Cforall,       // linkage
-                {},                     // attributes
-                { Function::Inline }
-            );
-
-            // forward decls to resolve use before decl problem for '|' routines
-            forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) );
-
-            sendOperatorFunction->stmts = sendBody;
-            declsToAddAfter.push_back( sendOperatorFunction );
-        }
+			// Generates: return receiver;
+			sendBody->push_back( new ReturnStmt( decl->location, new NameExpr( decl->location, "receiver" ) ) );
+
+			// put it all together into the complete function decl from above
+			FunctionDecl * sendOperatorFunction = new FunctionDecl(
+				decl->location,
+				"?|?",
+				{
+					new ObjectDecl(
+						decl->location,
+						"receiver",
+						ast::deepCopy( derivedActorRef )
+					),
+					new ObjectDecl(
+						decl->location,
+						"msg",
+						ast::deepCopy( derivedMsgRef )
+					)
+				},                      // params
+				{
+					new ObjectDecl(
+						decl->location,
+						"receiver_ret",
+						ast::deepCopy( derivedActorRef )
+					)
+				},
+				nullptr,               // body
+				{ Storage::Static },    // storage
+				Linkage::Cforall,       // linkage
+				{},                     // attributes
+				{ Function::Inline }
+			);
+
+			// forward decls to resolve use before decl problem for '|' routines
+			forwardDecls.insertDecl( *actorIter, *messageIter , ast::deepCopy( sendOperatorFunction ) );
+
+			sendOperatorFunction->stmts = sendBody;
+			declsToAddAfter.push_back( sendOperatorFunction );
+		}
 	}
 
   public:
-    GenFuncsCreateTables( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
-        const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 
-        FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 
-        requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {}
+	GenFuncsCreateTables( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
+		const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl,
+		FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),
+		requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {}
 };
 
@@ -452,76 +452,75 @@
 // generates the forward declarations of the send operator for actor routines
 struct FwdDeclOperator : public ast::WithDeclsToAdd<> {
-    unordered_set<const StructDecl *> & actorStructDecls;
-    unordered_set<const StructDecl *>  & messageStructDecls;
-    FwdDeclTable & forwardDecls;
-
-    // handles forward declaring the message operator
-    void postvisit( const StructDecl * decl ) {
-        list<FunctionDecl *> toAddAfter;
-        auto actorIter = actorStructDecls.find( decl );
-        if ( actorIter != actorStructDecls.end() ) { // this is a derived actor decl
-            // get list of fwd decls that we can now insert
-            toAddAfter = forwardDecls.updateDecl( decl, false );
-
-            // get rid of decl from actorStructDecls since we no longer need it
-            actorStructDecls.erase( actorIter );
-        } else {
-            auto messageIter = messageStructDecls.find( decl );
-            if ( messageIter == messageStructDecls.end() ) return;
-
-            toAddAfter = forwardDecls.updateDecl( decl, true );
-
-            // get rid of decl from messageStructDecls since we no longer need it
-            messageStructDecls.erase( messageIter );
-        }
-
-        // add the fwd decls to declsToAddAfter
-        for ( FunctionDecl * func : toAddAfter ) {
-            declsToAddAfter.push_back( func );
-        }
-    }
+	unordered_set<const StructDecl *> & actorStructDecls;
+	unordered_set<const StructDecl *>  & messageStructDecls;
+	FwdDeclTable & forwardDecls;
+
+	// handles forward declaring the message operator
+	void postvisit( const StructDecl * decl ) {
+		list<FunctionDecl *> toAddAfter;
+		auto actorIter = actorStructDecls.find( decl );
+		if ( actorIter != actorStructDecls.end() ) { // this is a derived actor decl
+			// get list of fwd decls that we can now insert
+			toAddAfter = forwardDecls.updateDecl( decl, false );
+
+			// get rid of decl from actorStructDecls since we no longer need it
+			actorStructDecls.erase( actorIter );
+		} else {
+			auto messageIter = messageStructDecls.find( decl );
+			if ( messageIter == messageStructDecls.end() ) return;
+
+			toAddAfter = forwardDecls.updateDecl( decl, true );
+
+			// get rid of decl from messageStructDecls since we no longer need it
+			messageStructDecls.erase( messageIter );
+		}
+
+		// add the fwd decls to declsToAddAfter
+		for ( FunctionDecl * func : toAddAfter ) {
+			declsToAddAfter.push_back( func );
+		}
+	}
 
   public:
-    FwdDeclOperator( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 
-        FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), forwardDecls(forwardDecls) {}
+	FwdDeclOperator( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls,
+		FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), forwardDecls(forwardDecls) {}
 };
 
 void implementActors( TranslationUnit & translationUnit ) {
-    // unordered_maps to collect all derived actor and message types
-    unordered_set<const StructDecl *> actorStructDecls;
-    unordered_set<const StructDecl *> messageStructDecls;
-    FwdDeclTable forwardDecls;
-
-    // for storing through the passes
-    // these are populated with various important struct decls
-    const StructDecl * requestDeclPtr = nullptr;
-    const EnumDecl * allocationDeclPtr = nullptr;
-    const StructDecl * actorDeclPtr = nullptr;
-    const StructDecl * msgDeclPtr = nullptr;
-
-    // double pointer to modify local ptrs above
-    const StructDecl ** requestDecl = &requestDeclPtr;
-    const EnumDecl ** allocationDecl = &allocationDeclPtr;
-    const StructDecl ** actorDecl = &actorDeclPtr;
-    const StructDecl ** msgDecl = &msgDeclPtr;
-
-    // first pass collects ptrs to allocation enum, request type, and generic receive fn typedef
-    // also populates maps of all derived actors and messages
-    Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl, 
-        allocationDecl, actorDecl, msgDecl );
-
-    // check that we have found all the decls we need from <actor.hfa>, if not no need to run the rest of this pass
-    if ( !allocationDeclPtr || !requestDeclPtr || !actorDeclPtr || !msgDeclPtr ) 
-        return;
-
-    // second pass locates all receive() routines that overload the generic receive fn
-    // it then generates the appropriate operator '|' send routines for the receive routines
-    Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl, 
-        allocationDecl, actorDecl, msgDecl, forwardDecls );
-
-    // The third pass forward declares operator '|' send routines
-    Pass<FwdDeclOperator>::run( translationUnit, actorStructDecls, messageStructDecls, forwardDecls );
+	// unordered_maps to collect all derived actor and message types
+	unordered_set<const StructDecl *> actorStructDecls;
+	unordered_set<const StructDecl *> messageStructDecls;
+	FwdDeclTable forwardDecls;
+
+	// for storing through the passes
+	// these are populated with various important struct decls
+	const StructDecl * requestDeclPtr = nullptr;
+	const EnumDecl * allocationDeclPtr = nullptr;
+	const StructDecl * actorDeclPtr = nullptr;
+	const StructDecl * msgDeclPtr = nullptr;
+
+	// double pointer to modify local ptrs above
+	const StructDecl ** requestDecl = &requestDeclPtr;
+	const EnumDecl ** allocationDecl = &allocationDeclPtr;
+	const StructDecl ** actorDecl = &actorDeclPtr;
+	const StructDecl ** msgDecl = &msgDeclPtr;
+
+	// first pass collects ptrs to allocation enum, request type, and generic receive fn typedef
+	// also populates maps of all derived actors and messages
+	Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,
+		allocationDecl, actorDecl, msgDecl );
+
+	// check that we have found all the decls we need from <actor.hfa>, if not no need to run the rest of this pass
+	if ( !allocationDeclPtr || !requestDeclPtr || !actorDeclPtr || !msgDeclPtr )
+		return;
+
+	// second pass locates all receive() routines that overload the generic receive fn
+	// it then generates the appropriate operator '|' send routines for the receive routines
+	Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,
+		allocationDecl, actorDecl, msgDecl, forwardDecls );
+
+	// The third pass forward declares operator '|' send routines
+	Pass<FwdDeclOperator>::run( translationUnit, actorStructDecls, messageStructDecls, forwardDecls );
 }
-
 
 } // namespace Concurrency
Index: src/Concurrency/Corun.cpp
===================================================================
--- src/Concurrency/Corun.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Concurrency/Corun.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -26,274 +26,274 @@
 
 struct CorunKeyword : public WithDeclsToAdd<>, public WithStmtsToAdd<> {
-    UniqueName CorunFnNamer = "__CFA_corun_lambda_"s;
-    UniqueName CoforFnNamer = "__CFA_cofor_lambda_"s;
-    // UniqueName CoforFnVarNamer = "__CFA_cofor_lambda_var"s;
-    UniqueName RunnerBlockNamer = "__CFA_corun_block_"s;
-    
-    string coforArgName = "__CFA_cofor_lambda_arg";
-    string numProcsName = "__CFA_cofor_num_procs";
-    string currProcsName = "__CFA_cofor_curr_procs";
-    string thdArrName = "__CFA_cofor_thread_array";
-    string loopTempName = "__CFA_cofor_loop_temp";
-    
-
-    const StructDecl * runnerBlockDecl = nullptr;
-    const StructDecl * coforRunnerDecl = nullptr;
-
-    // Finds runner_block (corun task) and cofor_runner (cofor task) decls
-    void previsit( const StructDecl * decl ) {
-        if ( !decl->body ) {
-            return;
-        } else if ( "runner_block" == decl->name ) {
-            assert( !runnerBlockDecl );
-            runnerBlockDecl = decl;
-        } else if ( "cofor_runner" == decl->name ) {
-            assert( !coforRunnerDecl );
-            coforRunnerDecl = decl;
-        }
-    }
-
-    // codegen for cofor statements
-    Stmt * postvisit( const CoforStmt * stmt ) {
-        if ( !runnerBlockDecl || !coforRunnerDecl )
-            SemanticError( stmt->location, "To use cofor statements add #include <cofor.hfa>" );
-
-        if ( stmt->inits.size() != 1 )
-            SemanticError( stmt->location, "Cofor statements must have a single initializer in the loop control" );
-
-        if ( !stmt->body )
-            return nullptr;
-
-        const CodeLocation & loc = stmt->location;
-        const string fnName = CoforFnNamer.newName();
-
-        CompoundStmt * body = new CompoundStmt( loc );
-
-        // push back cofor initializer to generated body
-        body->push_back( deepCopy( stmt->inits.at(0) ) );
-
-        CompoundStmt * fnBody = new CompoundStmt( loc );
-
-        const DeclStmt * declStmtPtr = dynamic_cast<const DeclStmt *>(stmt->inits.at(0).get());
-        if ( ! declStmtPtr )
-            SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl statement?" );
-
-        const Decl * declPtr = dynamic_cast<const Decl *>(declStmtPtr->decl.get());
-        if ( ! declPtr )
-            SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl?" );
-
-        Type * initType = new TypeofType( new NameExpr( loc, declPtr->name ) );
-
-        // Generates:
-        // typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
-        fnBody->push_back( new DeclStmt( loc, 
-            new ObjectDecl( loc,
-                declPtr->name,
-                initType,
-                new SingleInit( loc,
-                    UntypedExpr::createDeref( loc,
-                        new CastExpr( loc, 
-                            new NameExpr( loc, coforArgName ), 
-                            new PointerType( initType ), ExplicitCast
-                        )
-                    )
-                )
-            )
-        ));
-
-        // push rest of cofor body into loop lambda
-        fnBody->push_back( deepCopy( stmt->body ) );
-
-        // Generates:
-        // void __CFA_cofor_lambda_() {
-        //    typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
-        //    stmt->body;
-        // }
-        Stmt * coforLambda = new DeclStmt( loc,
-            new FunctionDecl( loc,
-                fnName,                                             // name
-                {
-                    new ObjectDecl( loc,
-                        coforArgName,
-                        new ast::PointerType( new ast::VoidType() )
-                    )
-                },                                                  // params
-                {},                                                 // return
-                fnBody   // body
-            )
-        );
-        body->push_back( coforLambda );
-
-        // Generates:
-        // unsigned __CFA_cofor_num_procs = get_proc_count();
-        body->push_back( new DeclStmt( loc,
-                new ObjectDecl( loc,
-                    numProcsName,
-                    new BasicType( BasicKind::UnsignedInt ),
-                    new SingleInit( loc, 
-                        new UntypedExpr( loc,
-                            new NameExpr( loc, "get_proc_count" ),
-                            {}
-                        )
-                    )
-                )
-            )
-        );
-
-        // Generates:
-        // unsigned __CFA_cofor_curr_procs = 0;
-        body->push_back( new DeclStmt( loc,
-                new ObjectDecl( loc,
-                    currProcsName,
-                    new BasicType( BasicKind::UnsignedInt ),
-                    new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
-                )
-            )
-        );
-
-        // Generates:
-        // unsigned cofor_runner __CFA_cofor_thread_array[nprocs];
-        body->push_back( new DeclStmt( loc,
-                new ObjectDecl( loc,
-                    thdArrName,
-                    new ast::ArrayType(
-                        new StructInstType( coforRunnerDecl ),
-                        new NameExpr( loc, numProcsName ),
-                        ast::FixedLen,
-                        ast::DynamicDim
-                    )
-                )
-            )
-        );
-
-        // Generates:
-        // start_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs, __CFA_cofor_lambda_ );
-        body->push_back( new ExprStmt( loc,
-            new UntypedExpr( loc,
-                new NameExpr( loc, "start_runners" ),
-                {
-                    new NameExpr( loc, thdArrName ),
-                    new NameExpr( loc, numProcsName ),
-                    new NameExpr( loc, fnName )
-                }
-            )
-        ));
-
-        // Generates:
-        // typeof(initializer) * __CFA_cofor_loop_temp = malloc();
-        CompoundStmt * forLoopBody = new CompoundStmt( loc );
-        forLoopBody->push_back( new DeclStmt( loc,
-                new ObjectDecl( loc,
-                    loopTempName,
-                    new PointerType( initType ),
-                    new SingleInit( loc, 
-                        new UntypedExpr( loc,
-                            new NameExpr( loc, "malloc" ),
-                            {}
-                        )
-                    )
-                )
-            )
-        );
-
-        // Generates:
-        // *__CFA_cofor_loop_temp = initializer;
-        forLoopBody->push_back( new ExprStmt( loc,
-            UntypedExpr::createAssign( loc,
-                UntypedExpr::createDeref( loc, new NameExpr( loc, loopTempName ) ),
-                new NameExpr( loc, declPtr->name )
-            )
-        ));
-
-        // Generates:
-        // send_work( __CFA_cofor_thread_array, __CFA_cofor_num_procs,
-        //     __CFA_cofor_curr_procs, __CFA_cofor_loop_temp );
-        forLoopBody->push_back( new ExprStmt( loc,
-            new UntypedExpr( loc,
-                new NameExpr( loc, "send_work" ),
-                {
-                    new NameExpr( loc, thdArrName ),
-                    new NameExpr( loc, numProcsName ),
-                    new NameExpr( loc, currProcsName ),
-                    new NameExpr( loc, loopTempName )
-                }
-            )
-        ));
-
-        body->push_back( new ForStmt( loc,
-            {},
-            deepCopy( stmt->cond ),
-            deepCopy( stmt->inc ),
-            forLoopBody
-        ));
-
-        // Generates:
-        // end_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs );
-        body->push_back( new ExprStmt( loc,
-            new UntypedExpr( loc,
-                new NameExpr( loc, "end_runners" ),
-                {
-                    new NameExpr( loc, thdArrName ),
-                    new NameExpr( loc, numProcsName )
-                }
-            )
-        ));
-
-        return body;
-    }
-
-    // codegen for corun statements
-    Stmt * postvisit( const CorunStmt * stmt ) {
-        if ( !runnerBlockDecl || !coforRunnerDecl )
-            SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>" );
-
-        if ( !stmt->stmt )
-            return nullptr;
-
-        const CodeLocation & loc = stmt->location;
-        const string fnName = CorunFnNamer.newName();
-        const string objName = RunnerBlockNamer.newName();
-
-        // Generates:
-        // void __CFA_corun_lambda_() { ... stmt->stmt ... }
-        Stmt * runnerLambda = new DeclStmt( loc,
-            new FunctionDecl( loc,
-                fnName,                                             // name
-                {},                                                 // params
-                {},                                                 // return
-                new CompoundStmt( loc, { deepCopy(stmt->stmt) } )   // body
-            )
-        );
-
-        // Generates:
-        // runner_block __CFA_corun_block_;
-        Stmt * objDecl = new DeclStmt( loc,
-            new ObjectDecl( loc,
-                objName,
-                new StructInstType( runnerBlockDecl )
-            )
-        );
-
-        // Generates:
-        // __CFA_corun_block_{ __CFA_corun_lambda_ };
-        Stmt * threadStart = new ExprStmt( loc,
-            new UntypedExpr ( loc,
-                new NameExpr( loc, "?{}" ),
-                {
-                    new NameExpr( loc, objName ),
-                    new NameExpr( loc, fnName )
-                }
-            )
-        );
-
-        stmtsToAddBefore.push_back( runnerLambda );
-        stmtsToAddBefore.push_back( objDecl );
-
-        return threadStart;
-    }
+	UniqueName CorunFnNamer = "__CFA_corun_lambda_"s;
+	UniqueName CoforFnNamer = "__CFA_cofor_lambda_"s;
+	// UniqueName CoforFnVarNamer = "__CFA_cofor_lambda_var"s;
+	UniqueName RunnerBlockNamer = "__CFA_corun_block_"s;
+
+	string coforArgName = "__CFA_cofor_lambda_arg";
+	string numProcsName = "__CFA_cofor_num_procs";
+	string currProcsName = "__CFA_cofor_curr_procs";
+	string thdArrName = "__CFA_cofor_thread_array";
+	string loopTempName = "__CFA_cofor_loop_temp";
+
+
+	const StructDecl * runnerBlockDecl = nullptr;
+	const StructDecl * coforRunnerDecl = nullptr;
+
+	// Finds runner_block (corun task) and cofor_runner (cofor task) decls
+	void previsit( const StructDecl * decl ) {
+		if ( !decl->body ) {
+			return;
+		} else if ( "runner_block" == decl->name ) {
+			assert( !runnerBlockDecl );
+			runnerBlockDecl = decl;
+		} else if ( "cofor_runner" == decl->name ) {
+			assert( !coforRunnerDecl );
+			coforRunnerDecl = decl;
+		}
+	}
+
+	// codegen for cofor statements
+	Stmt * postvisit( const CoforStmt * stmt ) {
+		if ( !runnerBlockDecl || !coforRunnerDecl )
+			SemanticError( stmt->location, "To use cofor statements add #include <cofor.hfa>" );
+
+		if ( stmt->inits.size() != 1 )
+			SemanticError( stmt->location, "Cofor statements must have a single initializer in the loop control" );
+
+		if ( !stmt->body )
+			return nullptr;
+
+		const CodeLocation & loc = stmt->location;
+		const string fnName = CoforFnNamer.newName();
+
+		CompoundStmt * body = new CompoundStmt( loc );
+
+		// push back cofor initializer to generated body
+		body->push_back( deepCopy( stmt->inits.at(0) ) );
+
+		CompoundStmt * fnBody = new CompoundStmt( loc );
+
+		const DeclStmt * declStmtPtr = dynamic_cast<const DeclStmt *>(stmt->inits.at(0).get());
+		if ( ! declStmtPtr )
+			SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl statement?" );
+
+		const Decl * declPtr = dynamic_cast<const Decl *>(declStmtPtr->decl.get());
+		if ( ! declPtr )
+			SemanticError( stmt->location, "Cofor statement initializer is somehow not a decl?" );
+
+		Type * initType = new TypeofType( new NameExpr( loc, declPtr->name ) );
+
+		// Generates:
+		// typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
+		fnBody->push_back( new DeclStmt( loc,
+			new ObjectDecl( loc,
+				declPtr->name,
+				initType,
+				new SingleInit( loc,
+					UntypedExpr::createDeref( loc,
+						new CastExpr( loc,
+							new NameExpr( loc, coforArgName ),
+							new PointerType( initType ), ExplicitCast
+						)
+					)
+				)
+			)
+		));
+
+		// push rest of cofor body into loop lambda
+		fnBody->push_back( deepCopy( stmt->body ) );
+
+		// Generates:
+		// void __CFA_cofor_lambda_() {
+		//    typeof(init) __CFA_cofor_lambda_var = *((typeof(init) *)val);
+		//    stmt->body;
+		// }
+		Stmt * coforLambda = new DeclStmt( loc,
+			new FunctionDecl( loc,
+				fnName,                                             // name
+				{
+					new ObjectDecl( loc,
+						coforArgName,
+						new ast::PointerType( new ast::VoidType() )
+					)
+				},                                                  // params
+				{},                                                 // return
+				fnBody   // body
+			)
+		);
+		body->push_back( coforLambda );
+
+		// Generates:
+		// unsigned __CFA_cofor_num_procs = get_proc_count();
+		body->push_back( new DeclStmt( loc,
+				new ObjectDecl( loc,
+					numProcsName,
+					new BasicType( BasicKind::UnsignedInt ),
+					new SingleInit( loc,
+						new UntypedExpr( loc,
+							new NameExpr( loc, "get_proc_count" ),
+							{}
+						)
+					)
+				)
+			)
+		);
+
+		// Generates:
+		// unsigned __CFA_cofor_curr_procs = 0;
+		body->push_back( new DeclStmt( loc,
+				new ObjectDecl( loc,
+					currProcsName,
+					new BasicType( BasicKind::UnsignedInt ),
+					new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
+				)
+			)
+		);
+
+		// Generates:
+		// unsigned cofor_runner __CFA_cofor_thread_array[nprocs];
+		body->push_back( new DeclStmt( loc,
+				new ObjectDecl( loc,
+					thdArrName,
+					new ast::ArrayType(
+						new StructInstType( coforRunnerDecl ),
+						new NameExpr( loc, numProcsName ),
+						ast::FixedLen,
+						ast::DynamicDim
+					)
+				)
+			)
+		);
+
+		// Generates:
+		// start_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs, __CFA_cofor_lambda_ );
+		body->push_back( new ExprStmt( loc,
+			new UntypedExpr( loc,
+				new NameExpr( loc, "start_runners" ),
+				{
+					new NameExpr( loc, thdArrName ),
+					new NameExpr( loc, numProcsName ),
+					new NameExpr( loc, fnName )
+				}
+			)
+		));
+
+		// Generates:
+		// typeof(initializer) * __CFA_cofor_loop_temp = malloc();
+		CompoundStmt * forLoopBody = new CompoundStmt( loc );
+		forLoopBody->push_back( new DeclStmt( loc,
+				new ObjectDecl( loc,
+					loopTempName,
+					new PointerType( initType ),
+					new SingleInit( loc,
+						new UntypedExpr( loc,
+							new NameExpr( loc, "malloc" ),
+							{}
+						)
+					)
+				)
+			)
+		);
+
+		// Generates:
+		// *__CFA_cofor_loop_temp = initializer;
+		forLoopBody->push_back( new ExprStmt( loc,
+			UntypedExpr::createAssign( loc,
+				UntypedExpr::createDeref( loc, new NameExpr( loc, loopTempName ) ),
+				new NameExpr( loc, declPtr->name )
+			)
+		));
+
+		// Generates:
+		// send_work( __CFA_cofor_thread_array, __CFA_cofor_num_procs,
+		//     __CFA_cofor_curr_procs, __CFA_cofor_loop_temp );
+		forLoopBody->push_back( new ExprStmt( loc,
+			new UntypedExpr( loc,
+				new NameExpr( loc, "send_work" ),
+				{
+					new NameExpr( loc, thdArrName ),
+					new NameExpr( loc, numProcsName ),
+					new NameExpr( loc, currProcsName ),
+					new NameExpr( loc, loopTempName )
+				}
+			)
+		));
+
+		body->push_back( new ForStmt( loc,
+			{},
+			deepCopy( stmt->cond ),
+			deepCopy( stmt->inc ),
+			forLoopBody
+		));
+
+		// Generates:
+		// end_runners( __CFA_cofor_thread_array, __CFA_cofor_num_procs );
+		body->push_back( new ExprStmt( loc,
+			new UntypedExpr( loc,
+				new NameExpr( loc, "end_runners" ),
+				{
+					new NameExpr( loc, thdArrName ),
+					new NameExpr( loc, numProcsName )
+				}
+			)
+		));
+
+		return body;
+	}
+
+	// codegen for corun statements
+	Stmt * postvisit( const CorunStmt * stmt ) {
+		if ( !runnerBlockDecl || !coforRunnerDecl )
+			SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>" );
+
+		if ( !stmt->stmt )
+			return nullptr;
+
+		const CodeLocation & loc = stmt->location;
+		const string fnName = CorunFnNamer.newName();
+		const string objName = RunnerBlockNamer.newName();
+
+		// Generates:
+		// void __CFA_corun_lambda_() { ... stmt->stmt ... }
+		Stmt * runnerLambda = new DeclStmt( loc,
+			new FunctionDecl( loc,
+				fnName,                                             // name
+				{},                                                 // params
+				{},                                                 // return
+				new CompoundStmt( loc, { deepCopy(stmt->stmt) } )   // body
+			)
+		);
+
+		// Generates:
+		// runner_block __CFA_corun_block_;
+		Stmt * objDecl = new DeclStmt( loc,
+			new ObjectDecl( loc,
+				objName,
+				new StructInstType( runnerBlockDecl )
+			)
+		);
+
+		// Generates:
+		// __CFA_corun_block_{ __CFA_corun_lambda_ };
+		Stmt * threadStart = new ExprStmt( loc,
+			new UntypedExpr ( loc,
+				new NameExpr( loc, "?{}" ),
+				{
+					new NameExpr( loc, objName ),
+					new NameExpr( loc, fnName )
+				}
+			)
+		);
+
+		stmtsToAddBefore.push_back( runnerLambda );
+		stmtsToAddBefore.push_back( objDecl );
+
+		return threadStart;
+	}
 };
 
 void implementCorun( TranslationUnit & translationUnit ) {
-    Pass<CorunKeyword>::run( translationUnit );
+	Pass<CorunKeyword>::run( translationUnit );
 }
 
Index: src/Concurrency/Keywords.cpp
===================================================================
--- src/Concurrency/Keywords.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Concurrency/Keywords.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -991,5 +991,5 @@
 	ast::CompoundStmt * body =
 			new ast::CompoundStmt( stmt->location, { stmt->stmt } );
-	
+
 	return addStatements( body, stmt->mutexObjs );;
 }
@@ -1180,5 +1180,5 @@
 
 // generates a cast to the void ptr to the appropriate lock type and dereferences it before calling lock or unlock on it
-// used to undo the type erasure done by storing all the lock pointers as void 
+// used to undo the type erasure done by storing all the lock pointers as void
 ast::ExprStmt * MutexKeyword::genVirtLockUnlockExpr( const std::string & fnName, ast::ptr<ast::Expr> expr, const CodeLocation & location, ast::Expr * param ) {
 	return new ast::ExprStmt( location,
@@ -1187,5 +1187,5 @@
 				ast::UntypedExpr::createDeref(
 					location,
-					new ast::CastExpr( location, 
+					new ast::CastExpr( location,
 						param,
 						new ast::PointerType( new ast::TypeofType( new ast::UntypedExpr(
@@ -1208,5 +1208,5 @@
 	//adds an if/elif clause for each lock to assign type from void ptr based on ptr address
 	for ( long unsigned int i = 0; i < args.size(); i++ ) {
-		
+
 		ast::UntypedExpr * ifCond = new ast::UntypedExpr( location,
 			new ast::NameExpr( location, "?==?" ), {
@@ -1216,10 +1216,10 @@
 		);
 
-		ast::IfStmt * currLockIf = new ast::IfStmt( 
+		ast::IfStmt * currLockIf = new ast::IfStmt(
 			location,
 			ifCond,
 			genVirtLockUnlockExpr( fnName, args.at(i), location, ast::deepCopy( thisParam ) )
 		);
-		
+
 		if ( i == 0 ) {
 			outerLockIf = currLockIf;
@@ -1235,9 +1235,9 @@
 
 void flattenTuple( const ast::UntypedTupleExpr * tuple, std::vector<ast::ptr<ast::Expr>> & output ) {
-    for ( auto & expr : tuple->exprs ) {
-        const ast::UntypedTupleExpr * innerTuple = dynamic_cast<const ast::UntypedTupleExpr *>(expr.get());
-        if ( innerTuple ) flattenTuple( innerTuple, output );
-        else output.emplace_back( ast::deepCopy( expr ));
-    }
+	for ( auto & expr : tuple->exprs ) {
+		const ast::UntypedTupleExpr * innerTuple = dynamic_cast<const ast::UntypedTupleExpr *>(expr.get());
+		if ( innerTuple ) flattenTuple( innerTuple, output );
+		else output.emplace_back( ast::deepCopy( expr ));
+	}
 }
 
@@ -1255,11 +1255,11 @@
 	// std::string unlockFnName = mutex_func_namer.newName();
 
-    // If any arguments to the mutex stmt are tuples, flatten them
-    std::vector<ast::ptr<ast::Expr>> flattenedArgs;
-    for ( auto & arg : args ) {
-        const ast::UntypedTupleExpr * tuple = dynamic_cast<const ast::UntypedTupleExpr *>(args.at(0).get());
-        if ( tuple ) flattenTuple( tuple, flattenedArgs );
-        else flattenedArgs.emplace_back( ast::deepCopy( arg ));
-    }
+	// If any arguments to the mutex stmt are tuples, flatten them
+	std::vector<ast::ptr<ast::Expr>> flattenedArgs;
+	for ( auto & arg : args ) {
+		const ast::UntypedTupleExpr * tuple = dynamic_cast<const ast::UntypedTupleExpr *>(args.at(0).get());
+		if ( tuple ) flattenTuple( tuple, flattenedArgs );
+		else flattenedArgs.emplace_back( ast::deepCopy( arg ));
+	}
 
 	// Make pointer to the monitors.
@@ -1302,5 +1302,5 @@
 	// adds a nested try stmt for each lock we are locking
 	for ( long unsigned int i = 0; i < flattenedArgs.size(); i++ ) {
-		ast::UntypedExpr * innerAccess = new ast::UntypedExpr( 
+		ast::UntypedExpr * innerAccess = new ast::UntypedExpr(
 			location,
 			new ast::NameExpr( location,"?[?]" ), {
@@ -1426,5 +1426,5 @@
 	// 	);
 
-	// 	ast::IfStmt * currLockIf = new ast::IfStmt( 
+	// 	ast::IfStmt * currLockIf = new ast::IfStmt(
 	// 		location,
 	// 		ast::deepCopy( ifCond ),
@@ -1432,10 +1432,10 @@
 	// 	);
 
-	// 	ast::IfStmt * currUnlockIf = new ast::IfStmt( 
+	// 	ast::IfStmt * currUnlockIf = new ast::IfStmt(
 	// 		location,
 	// 		ifCond,
 	// 		genVirtLockUnlockExpr( "unlock", args.at(i), location, ast::deepCopy( thisParam ) )
 	// 	);
-		
+
 	// 	if ( i == 0 ) {
 	// 		outerLockIf = currLockIf;
@@ -1450,5 +1450,5 @@
 	// 	lastUnlockIf = currUnlockIf;
 	// }
-	
+
 	// // add pointer typing if/elifs to body of routines
 	// lock_decl->stmts = new ast::CompoundStmt( location, { outerLockIf } );
Index: src/Concurrency/Waituntil.cpp
===================================================================
--- src/Concurrency/Waituntil.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Concurrency/Waituntil.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -31,7 +31,7 @@
 /* So this is what this pass dones:
 {
-    when ( condA ) waituntil( A ){ doA(); } 
-    or when ( condB ) waituntil( B ){ doB(); } 
-    and when ( condC ) waituntil( C ) { doC(); }
+	when ( condA ) waituntil( A ){ doA(); }
+	or when ( condB ) waituntil( B ){ doB(); }
+	and when ( condC ) waituntil( C ) { doC(); }
 }
 		 ||
@@ -42,89 +42,89 @@
 Generates these two routines:
 static inline bool is_full_sat_1( int * clause_statuses ) {
-    return clause_statuses[0] 
-        || clause_statuses[1]
-        && clause_statuses[2];
+	return clause_statuses[0]
+		|| clause_statuses[1]
+		&& clause_statuses[2];
 }
 
 static inline bool is_done_sat_1( int * clause_statuses ) {
-    return has_run(clause_statuses[0])
-        || has_run(clause_statuses[1])
-        && has_run(clause_statuses[2]);
+	return has_run(clause_statuses[0])
+		|| has_run(clause_statuses[1])
+		&& has_run(clause_statuses[2]);
 }
 
 Replaces the waituntil statement above with the following code:
 {
-    // used with atomic_dec/inc to get binary semaphore behaviour
-    int park_counter = 0;
-
-    // status (one for each clause)
-    int clause_statuses[3] = { 0 };
-
-    bool whenA = condA;
-    bool whenB = condB;
-    bool whenC = condC;
-
-    if ( !whenB ) clause_statuses[1] = __SELECT_RUN;
-    if ( !whenC ) clause_statuses[2] = __SELECT_RUN;
-
-    // some other conditional settors for clause_statuses are set here, see genSubtreeAssign and related routines
-
-    // three blocks
-    // for each block, create, setup, then register select_node
-    select_node clause1;
-    select_node clause2;
-    select_node clause3;
-
-    try {
-        if ( whenA ) { register_select(A, clause1); setup_clause( clause1, &clause_statuses[0], &park_counter ); }
-        ... repeat ^ for B and C ... 
-
-        // if else clause is defined a separate branch can occur here to set initial values, see genWhenStateConditions
-
-        // loop & park until done
-        while( !is_full_sat_1( clause_statuses ) ) {
-            
-            // binary sem P();
-            if ( __atomic_sub_fetch( &park_counter, 1, __ATOMIC_SEQ_CST) < 0 )
-                park();
-            
-            // execute any blocks available with status set to 0
-            for ( int i = 0; i < 3; i++ ) {
-                if (clause_statuses[i] == __SELECT_SAT) {
-                    switch (i) {
-                        case 0:
-                            try {
-                                    on_selected( A, clause1 );
-                                    doA();
-                            }
-                            finally { clause_statuses[i] = __SELECT_RUN; unregister_select(A, clause1); }
-                            break;
-                        case 1:
-                            ... same gen as A but for B and clause2 ...
-                            break;
-                        case 2:
-                            ... same gen as A but for C and clause3 ...
-                            break;
-                    }
-                }
-            }
-        }
-
-        // ensure that the blocks that triggered is_full_sat_1 are run
-        // by running every un-run block that is SAT from the start until
-        // the predicate is SAT when considering RUN status = true
-        for ( int i = 0; i < 3; i++ ) {
-            if (is_done_sat_1( clause_statuses )) break;
-            if (clause_statuses[i] == __SELECT_SAT)
-                ... Same if body here as in loop above ...
-        }
-    } finally {
-        // the unregister and on_selected calls are needed to support primitives where the acquire has side effects
-        // so the corresponding block MUST be run for those primitives to not lose state (example is channels)
-        if ( !has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) )
-            on_selected( A, clause1 )
-            doA(); 
-        ... repeat if above for B and C ...
-    }
+	// used with atomic_dec/inc to get binary semaphore behaviour
+	int park_counter = 0;
+
+	// status (one for each clause)
+	int clause_statuses[3] = { 0 };
+
+	bool whenA = condA;
+	bool whenB = condB;
+	bool whenC = condC;
+
+	if ( !whenB ) clause_statuses[1] = __SELECT_RUN;
+	if ( !whenC ) clause_statuses[2] = __SELECT_RUN;
+
+	// some other conditional settors for clause_statuses are set here, see genSubtreeAssign and related routines
+
+	// three blocks
+	// for each block, create, setup, then register select_node
+	select_node clause1;
+	select_node clause2;
+	select_node clause3;
+
+	try {
+		if ( whenA ) { register_select(A, clause1); setup_clause( clause1, &clause_statuses[0], &park_counter ); }
+		... repeat ^ for B and C ...
+
+		// if else clause is defined a separate branch can occur here to set initial values, see genWhenStateConditions
+
+		// loop & park until done
+		while( !is_full_sat_1( clause_statuses ) ) {
+
+			// binary sem P();
+			if ( __atomic_sub_fetch( &park_counter, 1, __ATOMIC_SEQ_CST) < 0 )
+				park();
+
+			// execute any blocks available with status set to 0
+			for ( int i = 0; i < 3; i++ ) {
+				if (clause_statuses[i] == __SELECT_SAT) {
+				    switch (i) {
+				        case 0:
+				            try {
+				                    on_selected( A, clause1 );
+				                    doA();
+				            }
+				            finally { clause_statuses[i] = __SELECT_RUN; unregister_select(A, clause1); }
+				            break;
+				        case 1:
+				            ... same gen as A but for B and clause2 ...
+				            break;
+				        case 2:
+				            ... same gen as A but for C and clause3 ...
+				            break;
+				    }
+				}
+			}
+		}
+
+		// ensure that the blocks that triggered is_full_sat_1 are run
+		// by running every un-run block that is SAT from the start until
+		// the predicate is SAT when considering RUN status = true
+		for ( int i = 0; i < 3; i++ ) {
+			if (is_done_sat_1( clause_statuses )) break;
+			if (clause_statuses[i] == __SELECT_SAT)
+				... Same if body here as in loop above ...
+		}
+	} finally {
+		// the unregister and on_selected calls are needed to support primitives where the acquire has side effects
+		// so the corresponding block MUST be run for those primitives to not lose state (example is channels)
+		if ( !has_run(clause_statuses[0]) && whenA && unregister_select(A, clause1) )
+			on_selected( A, clause1 )
+			doA();
+		... repeat if above for B and C ...
+	}
 }
 
@@ -134,63 +134,63 @@
 
 class GenerateWaitUntilCore final {
-    vector<FunctionDecl *> & satFns;
+	vector<FunctionDecl *> & satFns;
 	UniqueName namer_sat = "__is_full_sat_"s;
-    UniqueName namer_run = "__is_run_sat_"s;
+	UniqueName namer_run = "__is_run_sat_"s;
 	UniqueName namer_park = "__park_counter_"s;
 	UniqueName namer_status = "__clause_statuses_"s;
 	UniqueName namer_node = "__clause_"s;
-    UniqueName namer_target = "__clause_target_"s;
-    UniqueName namer_when = "__when_cond_"s;
-    UniqueName namer_label = "__waituntil_label_"s;
-
-    string idxName = "__CFA_clause_idx_";
-
-    struct ClauseData {
-        string nodeName;
-        string targetName;
-        string whenName;
-        int index;
-        string & statusName;
-        ClauseData( int index, string & statusName ) : index(index), statusName(statusName) {}
-    };
-
-    const StructDecl * selectNodeDecl = nullptr;
-
-    // This first set of routines are all used to do the complicated job of 
-    //    dealing with how to set predicate statuses with certain when_conds T/F
-    //    so that the when_cond == F effectively makes that clause "disappear"
-    void updateAmbiguousWhen( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool andBelow, bool orBelow );
-    void paintWhenTree( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool & andBelow, bool & orBelow );
-    bool paintWhenTree( WaitUntilStmt::ClauseNode * currNode );
-    void collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs, int & index, bool parentAmbig, bool parentAnd );
-    void collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs );
-    void updateWhenState( WaitUntilStmt::ClauseNode * currNode );
-    void genSubtreeAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, bool status, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData );
-    void genStatusAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData );
-    CompoundStmt * getStatusAssignment( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData );
-    Stmt * genWhenStateConditions( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigClauses, vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type ambigIdx );
-
-    // These routines are just code-gen helpers
-    void addPredicates( const WaitUntilStmt * stmt, string & satName, string & runName );
-    void setUpClause( const WhenClause * clause, ClauseData * data, string & pCountName, CompoundStmt * body );
-    CompoundStmt * genStatusCheckFor( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, string & predName );
-    Expr * genSelectTraitCall( const WhenClause * clause, const ClauseData * data, string fnName );
-    CompoundStmt * genStmtBlock( const WhenClause * clause, const ClauseData * data );
-    Stmt * genElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, vector<ClauseData *> & clauseData );
-    Stmt * genNoElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, string & pCountName, vector<ClauseData *> & clauseData );
-    void genClauseInits( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, CompoundStmt * body, string & statusName, string & elseWhenName );
-    Stmt * recursiveOrIfGen( const WaitUntilStmt * stmt, vector<ClauseData *> & data, vector<ClauseData*>::size_type idx, string & elseWhenName );
-    Stmt * buildOrCaseSwitch( const WaitUntilStmt * stmt, string & statusName, vector<ClauseData *> & data );
-    Stmt * genAllOr( const WaitUntilStmt * stmt );
+	UniqueName namer_target = "__clause_target_"s;
+	UniqueName namer_when = "__when_cond_"s;
+	UniqueName namer_label = "__waituntil_label_"s;
+
+	string idxName = "__CFA_clause_idx_";
+
+	struct ClauseData {
+		string nodeName;
+		string targetName;
+		string whenName;
+		int index;
+		string & statusName;
+		ClauseData( int index, string & statusName ) : index(index), statusName(statusName) {}
+	};
+
+	const StructDecl * selectNodeDecl = nullptr;
+
+	// This first set of routines are all used to do the complicated job of
+	//    dealing with how to set predicate statuses with certain when_conds T/F
+	//    so that the when_cond == F effectively makes that clause "disappear"
+	void updateAmbiguousWhen( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool andBelow, bool orBelow );
+	void paintWhenTree( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool & andBelow, bool & orBelow );
+	bool paintWhenTree( WaitUntilStmt::ClauseNode * currNode );
+	void collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs, int & index, bool parentAmbig, bool parentAnd );
+	void collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs );
+	void updateWhenState( WaitUntilStmt::ClauseNode * currNode );
+	void genSubtreeAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, bool status, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData );
+	void genStatusAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData );
+	CompoundStmt * getStatusAssignment( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData );
+	Stmt * genWhenStateConditions( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigClauses, vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type ambigIdx );
+
+	// These routines are just code-gen helpers
+	void addPredicates( const WaitUntilStmt * stmt, string & satName, string & runName );
+	void setUpClause( const WhenClause * clause, ClauseData * data, string & pCountName, CompoundStmt * body );
+	CompoundStmt * genStatusCheckFor( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, string & predName );
+	Expr * genSelectTraitCall( const WhenClause * clause, const ClauseData * data, string fnName );
+	CompoundStmt * genStmtBlock( const WhenClause * clause, const ClauseData * data );
+	Stmt * genElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, vector<ClauseData *> & clauseData );
+	Stmt * genNoElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, string & pCountName, vector<ClauseData *> & clauseData );
+	void genClauseInits( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, CompoundStmt * body, string & statusName, string & elseWhenName );
+	Stmt * recursiveOrIfGen( const WaitUntilStmt * stmt, vector<ClauseData *> & data, vector<ClauseData*>::size_type idx, string & elseWhenName );
+	Stmt * buildOrCaseSwitch( const WaitUntilStmt * stmt, string & statusName, vector<ClauseData *> & data );
+	Stmt * genAllOr( const WaitUntilStmt * stmt );
 
   public:
-    void previsit( const StructDecl * decl );
+	void previsit( const StructDecl * decl );
 	Stmt * postvisit( const WaitUntilStmt * stmt );
-    GenerateWaitUntilCore( vector<FunctionDecl *> & satFns ): satFns(satFns) {}
+	GenerateWaitUntilCore( vector<FunctionDecl *> & satFns ): satFns(satFns) {}
 };
 
 // Finds select_node decl
 void GenerateWaitUntilCore::previsit( const StructDecl * decl ) {
-    if ( !decl->body ) {
+	if ( !decl->body ) {
 		return;
 	} else if ( "select_node" == decl->name ) {
@@ -201,9 +201,9 @@
 
 void GenerateWaitUntilCore::updateAmbiguousWhen( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool andBelow, bool orBelow ) {
-    // all children when-ambiguous
-    if ( currNode->left->ambiguousWhen && currNode->right->ambiguousWhen )
-        // true iff an ancestor/descendant has a different operation
-        currNode->ambiguousWhen = (orAbove || orBelow) && (andBelow || andAbove);
-    // ambiguousWhen is initially false so theres no need to set it here
+	// all children when-ambiguous
+	if ( currNode->left->ambiguousWhen && currNode->right->ambiguousWhen )
+		// true iff an ancestor/descendant has a different operation
+		currNode->ambiguousWhen = (orAbove || orBelow) && (andBelow || andAbove);
+	// ambiguousWhen is initially false so theres no need to set it here
 }
 
@@ -215,36 +215,36 @@
 // - All of its descendent clauses are optional, i.e. they have a when_cond defined on the WhenClause
 void GenerateWaitUntilCore::paintWhenTree( WaitUntilStmt::ClauseNode * currNode, bool andAbove, bool orAbove, bool & andBelow, bool & orBelow ) {
-    bool aBelow = false; // updated by child nodes
-    bool oBelow = false; // updated by child nodes
-    switch (currNode->op) {
-        case WaitUntilStmt::ClauseNode::AND:
-            paintWhenTree( currNode->left, true, orAbove, aBelow, oBelow );
-            paintWhenTree( currNode->right, true, orAbove, aBelow, oBelow );
-
-            // update currNode's when flag based on conditions listed in fn signature comment above
-            updateAmbiguousWhen(currNode, true, orAbove, aBelow, oBelow );
-
-            // set return flags to tell parents which decendant ops have been seen
-            andBelow = true;
-            orBelow = oBelow;
-            return;
-        case WaitUntilStmt::ClauseNode::OR:
-            paintWhenTree( currNode->left, andAbove, true, aBelow, oBelow );
-            paintWhenTree( currNode->right, andAbove, true, aBelow, oBelow );
-
-            // update currNode's when flag based on conditions listed in fn signature comment above
-            updateAmbiguousWhen(currNode, andAbove, true, aBelow, oBelow );
-
-            // set return flags to tell parents which decendant ops have been seen
-            andBelow = aBelow;
-            orBelow = true;
-            return;
-        case WaitUntilStmt::ClauseNode::LEAF:
-            if ( currNode->leaf->when_cond )
-                currNode->ambiguousWhen = true;
-            return;
-        default:
-            assertf(false, "Unreachable waituntil clause node type. How did you get here???");
-    }
+	bool aBelow = false; // updated by child nodes
+	bool oBelow = false; // updated by child nodes
+	switch (currNode->op) {
+		case WaitUntilStmt::ClauseNode::AND:
+			paintWhenTree( currNode->left, true, orAbove, aBelow, oBelow );
+			paintWhenTree( currNode->right, true, orAbove, aBelow, oBelow );
+
+			// update currNode's when flag based on conditions listed in fn signature comment above
+			updateAmbiguousWhen(currNode, true, orAbove, aBelow, oBelow );
+
+			// set return flags to tell parents which decendant ops have been seen
+			andBelow = true;
+			orBelow = oBelow;
+			return;
+		case WaitUntilStmt::ClauseNode::OR:
+			paintWhenTree( currNode->left, andAbove, true, aBelow, oBelow );
+			paintWhenTree( currNode->right, andAbove, true, aBelow, oBelow );
+
+			// update currNode's when flag based on conditions listed in fn signature comment above
+			updateAmbiguousWhen(currNode, andAbove, true, aBelow, oBelow );
+
+			// set return flags to tell parents which decendant ops have been seen
+			andBelow = aBelow;
+			orBelow = true;
+			return;
+		case WaitUntilStmt::ClauseNode::LEAF:
+			if ( currNode->leaf->when_cond )
+				currNode->ambiguousWhen = true;
+			return;
+		default:
+			assertf(false, "Unreachable waituntil clause node type. How did you get here???");
+	}
 }
 
@@ -252,18 +252,18 @@
 // returns true if entire tree is OR's (special case)
 bool GenerateWaitUntilCore::paintWhenTree( WaitUntilStmt::ClauseNode * currNode ) {
-    bool aBelow = false, oBelow = false; // unused by initial call
-    paintWhenTree( currNode, false, false, aBelow, oBelow );
-    return !aBelow;
+	bool aBelow = false, oBelow = false; // unused by initial call
+	paintWhenTree( currNode, false, false, aBelow, oBelow );
+	return !aBelow;
 }
 
 // Helper: returns Expr that represents arrName[index]
 Expr * genArrAccessExpr( const CodeLocation & loc, int index, string arrName ) {
-    return new UntypedExpr ( loc, 
-        new NameExpr( loc, "?[?]" ),
-        {
-            new NameExpr( loc, arrName ),
-            ConstantExpr::from_int( loc, index )
-        }
-    );
+	return new UntypedExpr ( loc,
+		new NameExpr( loc, "?[?]" ),
+		{
+			new NameExpr( loc, arrName ),
+			ConstantExpr::from_int( loc, index )
+		}
+	);
 }
 
@@ -273,35 +273,35 @@
 // - updates LEAF nodes to be when-ambiguous if their direct parent is when-ambiguous.
 void GenerateWaitUntilCore::collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs, int & index, bool parentAmbig, bool parentAnd ) {
-    switch (currNode->op) {
-        case WaitUntilStmt::ClauseNode::AND:
-            collectWhens( currNode->left, ambigIdxs, andIdxs, index, currNode->ambiguousWhen, true );
-            collectWhens( currNode->right,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, true );
-            return;
-        case WaitUntilStmt::ClauseNode::OR:
-            collectWhens( currNode->left,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, false );
-            collectWhens( currNode->right,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, false );
-            return;
-        case WaitUntilStmt::ClauseNode::LEAF:
-            if ( parentAmbig ) {
-                ambigIdxs.push_back(make_pair(index, currNode));
-            }
-            if ( parentAnd && currNode->leaf->when_cond ) {
-                currNode->childOfAnd = true;
-                andIdxs.push_back(index);
-            }
-            index++;
-            return;
-        default:
-            assertf(false, "Unreachable waituntil clause node type. How did you get here???");
-    }
+	switch (currNode->op) {
+		case WaitUntilStmt::ClauseNode::AND:
+			collectWhens( currNode->left, ambigIdxs, andIdxs, index, currNode->ambiguousWhen, true );
+			collectWhens( currNode->right,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, true );
+			return;
+		case WaitUntilStmt::ClauseNode::OR:
+			collectWhens( currNode->left,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, false );
+			collectWhens( currNode->right,  ambigIdxs, andIdxs, index, currNode->ambiguousWhen, false );
+			return;
+		case WaitUntilStmt::ClauseNode::LEAF:
+			if ( parentAmbig ) {
+				ambigIdxs.push_back(make_pair(index, currNode));
+			}
+			if ( parentAnd && currNode->leaf->when_cond ) {
+				currNode->childOfAnd = true;
+				andIdxs.push_back(index);
+			}
+			index++;
+			return;
+		default:
+			assertf(false, "Unreachable waituntil clause node type. How did you get here???");
+	}
 }
 
 // overloaded wrapper for collectWhens that sets initial values
 void GenerateWaitUntilCore::collectWhens( WaitUntilStmt::ClauseNode * currNode, vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigIdxs, vector<int> & andIdxs ) {
-    int idx = 0;
-    collectWhens( currNode, ambigIdxs, andIdxs, idx, false, false );
-}
-
-// recursively updates ClauseNode whenState on internal nodes so that next pass can see which 
+	int idx = 0;
+	collectWhens( currNode, ambigIdxs, andIdxs, idx, false, false );
+}
+
+// recursively updates ClauseNode whenState on internal nodes so that next pass can see which
 //    subtrees are "turned off"
 // sets whenState = false iff both children have whenState == false.
@@ -309,11 +309,11 @@
 // since the ambiguous clauses were filtered in paintWhenTree we don't need to worry about that here
 void GenerateWaitUntilCore::updateWhenState( WaitUntilStmt::ClauseNode * currNode ) {
-    if ( currNode->op == WaitUntilStmt::ClauseNode::LEAF ) return;
-    updateWhenState( currNode->left );
-    updateWhenState( currNode->right );
-    if ( !currNode->left->whenState && !currNode->right->whenState )
-        currNode->whenState = false;
-    else 
-        currNode->whenState = true;
+	if ( currNode->op == WaitUntilStmt::ClauseNode::LEAF ) return;
+	updateWhenState( currNode->left );
+	updateWhenState( currNode->right );
+	if ( !currNode->left->whenState && !currNode->right->whenState )
+		currNode->whenState = false;
+	else
+		currNode->whenState = true;
 }
 
@@ -321,152 +321,152 @@
 // assumes that this will only be called on subtrees that are entirely whenState == false
 void GenerateWaitUntilCore::genSubtreeAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, bool status, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData ) {
-    if ( ( currNode->op == WaitUntilStmt::ClauseNode::AND && status )
-        || ( currNode->op == WaitUntilStmt::ClauseNode::OR && !status ) ) {
-        // need to recurse on both subtrees if && subtree needs to be true or || subtree needs to be false
-        genSubtreeAssign( stmt, currNode->left, status, idx, retStmt, clauseData );
-        genSubtreeAssign( stmt, currNode->right, status, idx, retStmt, clauseData );
-    } else if ( ( currNode->op == WaitUntilStmt::ClauseNode::OR && status )
-        || ( currNode->op == WaitUntilStmt::ClauseNode::AND && !status ) ) {
-        // only one subtree needs to evaluate to status if && subtree needs to be true or || subtree needs to be false
-        CompoundStmt * leftStmt = new CompoundStmt( stmt->location );
-        CompoundStmt * rightStmt = new CompoundStmt( stmt->location );
-
-        // only one side needs to evaluate to status so we recurse on both subtrees
-        //    but only keep the statements from the subtree with minimal statements
-        genSubtreeAssign( stmt, currNode->left, status, idx, leftStmt, clauseData );
-        genSubtreeAssign( stmt, currNode->right, status, idx, rightStmt, clauseData );
-        
-        // append minimal statements to retStmt
-        if ( leftStmt->kids.size() < rightStmt->kids.size() ) {
-            retStmt->kids.splice( retStmt->kids.end(), leftStmt->kids );
-        } else {
-            retStmt->kids.splice( retStmt->kids.end(), rightStmt->kids );
-        }
-        
-        delete leftStmt;
-        delete rightStmt;
-    } else if ( currNode->op == WaitUntilStmt::ClauseNode::LEAF ) {
-        const CodeLocation & loc = stmt->location;
-        if ( status && !currNode->childOfAnd ) {
-            retStmt->push_back(
-                new ExprStmt( loc, 
-                    UntypedExpr::createAssign( loc,
-                        genArrAccessExpr( loc, idx, clauseData.at(idx)->statusName ),
-                        new NameExpr( loc, "__SELECT_RUN" )
-                    )
-                )
-            );
-        } else if ( !status && currNode->childOfAnd ) {
-            retStmt->push_back(
-                new ExprStmt( loc, 
-                    UntypedExpr::createAssign( loc,
-                        genArrAccessExpr( loc, idx, clauseData.at(idx)->statusName ),
-                        new NameExpr( loc, "__SELECT_UNSAT" )
-                    )
-                )
-            );
-        }
-
-        // No need to generate statements for the following cases since childOfAnd are always set to true
-        //    and !childOfAnd are always false
-        // - status && currNode->childOfAnd
-        // - !status && !currNode->childOfAnd
-        idx++;
-    }
+	if ( ( currNode->op == WaitUntilStmt::ClauseNode::AND && status )
+		|| ( currNode->op == WaitUntilStmt::ClauseNode::OR && !status ) ) {
+		// need to recurse on both subtrees if && subtree needs to be true or || subtree needs to be false
+		genSubtreeAssign( stmt, currNode->left, status, idx, retStmt, clauseData );
+		genSubtreeAssign( stmt, currNode->right, status, idx, retStmt, clauseData );
+	} else if ( ( currNode->op == WaitUntilStmt::ClauseNode::OR && status )
+		|| ( currNode->op == WaitUntilStmt::ClauseNode::AND && !status ) ) {
+		// only one subtree needs to evaluate to status if && subtree needs to be true or || subtree needs to be false
+		CompoundStmt * leftStmt = new CompoundStmt( stmt->location );
+		CompoundStmt * rightStmt = new CompoundStmt( stmt->location );
+
+		// only one side needs to evaluate to status so we recurse on both subtrees
+		//    but only keep the statements from the subtree with minimal statements
+		genSubtreeAssign( stmt, currNode->left, status, idx, leftStmt, clauseData );
+		genSubtreeAssign( stmt, currNode->right, status, idx, rightStmt, clauseData );
+
+		// append minimal statements to retStmt
+		if ( leftStmt->kids.size() < rightStmt->kids.size() ) {
+			retStmt->kids.splice( retStmt->kids.end(), leftStmt->kids );
+		} else {
+			retStmt->kids.splice( retStmt->kids.end(), rightStmt->kids );
+		}
+
+		delete leftStmt;
+		delete rightStmt;
+	} else if ( currNode->op == WaitUntilStmt::ClauseNode::LEAF ) {
+		const CodeLocation & loc = stmt->location;
+		if ( status && !currNode->childOfAnd ) {
+			retStmt->push_back(
+				new ExprStmt( loc,
+				    UntypedExpr::createAssign( loc,
+				        genArrAccessExpr( loc, idx, clauseData.at(idx)->statusName ),
+				        new NameExpr( loc, "__SELECT_RUN" )
+				    )
+				)
+			);
+		} else if ( !status && currNode->childOfAnd ) {
+			retStmt->push_back(
+				new ExprStmt( loc,
+				    UntypedExpr::createAssign( loc,
+				        genArrAccessExpr( loc, idx, clauseData.at(idx)->statusName ),
+				        new NameExpr( loc, "__SELECT_UNSAT" )
+				    )
+				)
+			);
+		}
+
+		// No need to generate statements for the following cases since childOfAnd are always set to true
+		//    and !childOfAnd are always false
+		// - status && currNode->childOfAnd
+		// - !status && !currNode->childOfAnd
+		idx++;
+	}
 }
 
 void GenerateWaitUntilCore::genStatusAssign( const WaitUntilStmt * stmt, WaitUntilStmt::ClauseNode * currNode, int & idx, CompoundStmt * retStmt, vector<ClauseData *> & clauseData ) {
-    switch (currNode->op) {
-        case WaitUntilStmt::ClauseNode::AND:
-            // check which subtrees have all whenState == false (disabled)
-            if (!currNode->left->whenState && !currNode->right->whenState) {
-                // this case can only occur when whole tree is disabled since otherwise 
-                //    genStatusAssign( ... ) isn't called on nodes with whenState == false
-                assert( !currNode->whenState ); // paranoidWWW
-                // whole tree disabled so pass true so that select is SAT vacuously
-                genSubtreeAssign( stmt, currNode, true, idx, retStmt, clauseData );
-            } else if ( !currNode->left->whenState ) {
-                // pass true since x && true === x
-                genSubtreeAssign( stmt, currNode->left, true, idx, retStmt, clauseData );
-                genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
-            } else if ( !currNode->right->whenState ) {
-                genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
-                genSubtreeAssign( stmt, currNode->right, true, idx, retStmt, clauseData );
-            } else { 
-                // if no children with whenState == false recurse normally via break
-                break;
-            }
-            return;
-        case WaitUntilStmt::ClauseNode::OR:
-            if (!currNode->left->whenState && !currNode->right->whenState) {
-                assert( !currNode->whenState ); // paranoid
-                genSubtreeAssign( stmt, currNode, true, idx, retStmt, clauseData );
-            } else if ( !currNode->left->whenState ) {
-                // pass false since x || false === x
-                genSubtreeAssign( stmt, currNode->left, false, idx, retStmt, clauseData );
-                genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
-            } else if ( !currNode->right->whenState ) {
-                genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
-                genSubtreeAssign( stmt, currNode->right, false, idx, retStmt, clauseData );
-            } else { 
-                break;
-            }
-            return;
-        case WaitUntilStmt::ClauseNode::LEAF:
-            idx++;
-            return;
-        default:
-            assertf(false, "Unreachable waituntil clause node type. How did you get here???");
-    }
-    genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
-    genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
+	switch (currNode->op) {
+		case WaitUntilStmt::ClauseNode::AND:
+			// check which subtrees have all whenState == false (disabled)
+			if (!currNode->left->whenState && !currNode->right->whenState) {
+				// this case can only occur when whole tree is disabled since otherwise
+				//    genStatusAssign( ... ) isn't called on nodes with whenState == false
+				assert( !currNode->whenState ); // paranoidWWW
+				// whole tree disabled so pass true so that select is SAT vacuously
+				genSubtreeAssign( stmt, currNode, true, idx, retStmt, clauseData );
+			} else if ( !currNode->left->whenState ) {
+				// pass true since x && true === x
+				genSubtreeAssign( stmt, currNode->left, true, idx, retStmt, clauseData );
+				genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
+			} else if ( !currNode->right->whenState ) {
+				genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
+				genSubtreeAssign( stmt, currNode->right, true, idx, retStmt, clauseData );
+			} else {
+				// if no children with whenState == false recurse normally via break
+				break;
+			}
+			return;
+		case WaitUntilStmt::ClauseNode::OR:
+			if (!currNode->left->whenState && !currNode->right->whenState) {
+				assert( !currNode->whenState ); // paranoid
+				genSubtreeAssign( stmt, currNode, true, idx, retStmt, clauseData );
+			} else if ( !currNode->left->whenState ) {
+				// pass false since x || false === x
+				genSubtreeAssign( stmt, currNode->left, false, idx, retStmt, clauseData );
+				genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
+			} else if ( !currNode->right->whenState ) {
+				genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
+				genSubtreeAssign( stmt, currNode->right, false, idx, retStmt, clauseData );
+			} else {
+				break;
+			}
+			return;
+		case WaitUntilStmt::ClauseNode::LEAF:
+			idx++;
+			return;
+		default:
+			assertf(false, "Unreachable waituntil clause node type. How did you get here???");
+	}
+	genStatusAssign( stmt, currNode->left, idx, retStmt, clauseData );
+	genStatusAssign( stmt, currNode->right, idx, retStmt, clauseData );
 }
 
 // generates a minimal set of assignments for status arr based on which whens are toggled on/off
 CompoundStmt * GenerateWaitUntilCore::getStatusAssignment( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData ) {
-    updateWhenState( stmt->predicateTree );
-    CompoundStmt * retval = new CompoundStmt( stmt->location );
-    int idx = 0;
-    genStatusAssign( stmt, stmt->predicateTree, idx, retval, clauseData );
-    return retval;
+	updateWhenState( stmt->predicateTree );
+	CompoundStmt * retval = new CompoundStmt( stmt->location );
+	int idx = 0;
+	genStatusAssign( stmt, stmt->predicateTree, idx, retval, clauseData );
+	return retval;
 }
 
 // generates nested if/elses for all possible assignments of ambiguous when_conds
 // exponential size of code gen but linear runtime O(n), where n is number of ambiguous whens()
-Stmt * GenerateWaitUntilCore::genWhenStateConditions( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, 
-    vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigClauses, vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type ambigIdx ) {
-    // I hate C++ sometimes, using vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type for size() comparison seems silly.
-    //    Why is size_type parameterized on the type stored in the vector?????
-
-    const CodeLocation & loc = stmt->location;
-    int clauseIdx = ambigClauses.at(ambigIdx).first;
-    WaitUntilStmt::ClauseNode * currNode = ambigClauses.at(ambigIdx).second;
-    Stmt * thenStmt;
-    Stmt * elseStmt;
-    
-    if ( ambigIdx == ambigClauses.size() - 1 ) { // base case
-        currNode->whenState = true;
-        thenStmt = getStatusAssignment( stmt, clauseData );
-        currNode->whenState = false;
-        elseStmt = getStatusAssignment( stmt, clauseData );
-    } else {
-        // recurse both with when enabled and disabled to generate all possible cases
-        currNode->whenState = true;
-        thenStmt = genWhenStateConditions( stmt, clauseData, ambigClauses, ambigIdx + 1 );
-        currNode->whenState = false;
-        elseStmt = genWhenStateConditions( stmt, clauseData, ambigClauses, ambigIdx + 1 );
-    }
-
-    // insert first recursion result in if ( __when_cond_ ) { ... }
-    // insert second recursion result in else { ... }
-    return new CompoundStmt ( loc,
-        {
-            new IfStmt( loc,
-                new NameExpr( loc, clauseData.at(clauseIdx)->whenName ),
-                thenStmt,
-                elseStmt
-            )
-        }
-    );
+Stmt * GenerateWaitUntilCore::genWhenStateConditions( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData,
+	vector<pair<int, WaitUntilStmt::ClauseNode *>> & ambigClauses, vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type ambigIdx ) {
+	// I hate C++ sometimes, using vector<pair<int, WaitUntilStmt::ClauseNode *>>::size_type for size() comparison seems silly.
+	//    Why is size_type parameterized on the type stored in the vector?????
+
+	const CodeLocation & loc = stmt->location;
+	int clauseIdx = ambigClauses.at(ambigIdx).first;
+	WaitUntilStmt::ClauseNode * currNode = ambigClauses.at(ambigIdx).second;
+	Stmt * thenStmt;
+	Stmt * elseStmt;
+
+	if ( ambigIdx == ambigClauses.size() - 1 ) { // base case
+		currNode->whenState = true;
+		thenStmt = getStatusAssignment( stmt, clauseData );
+		currNode->whenState = false;
+		elseStmt = getStatusAssignment( stmt, clauseData );
+	} else {
+		// recurse both with when enabled and disabled to generate all possible cases
+		currNode->whenState = true;
+		thenStmt = genWhenStateConditions( stmt, clauseData, ambigClauses, ambigIdx + 1 );
+		currNode->whenState = false;
+		elseStmt = genWhenStateConditions( stmt, clauseData, ambigClauses, ambigIdx + 1 );
+	}
+
+	// insert first recursion result in if ( __when_cond_ ) { ... }
+	// insert second recursion result in else { ... }
+	return new CompoundStmt ( loc,
+		{
+			new IfStmt( loc,
+				new NameExpr( loc, clauseData.at(clauseIdx)->whenName ),
+				thenStmt,
+				elseStmt
+			)
+		}
+	);
 }
 
@@ -478,13 +478,13 @@
 // mutates index to be index + 1
 Expr * genSatExpr( const CodeLocation & loc, int & index ) {
-    return genArrAccessExpr( loc, index++, "clause_statuses" );
+	return genArrAccessExpr( loc, index++, "clause_statuses" );
 }
 
 // return Expr that represents has_run(clause_statuses[index])
 Expr * genRunExpr( const CodeLocation & loc, int & index ) {
-    return new UntypedExpr ( loc, 
-        new NameExpr( loc, "__CFA_has_clause_run" ),
-        { genSatExpr( loc, index ) }
-    );
+	return new UntypedExpr ( loc,
+		new NameExpr( loc, "__CFA_has_clause_run" ),
+		{ genSatExpr( loc, index ) }
+	);
 }
 
@@ -492,32 +492,32 @@
 // the predicate expr used inside the predicate functions
 Expr * genPredExpr( const CodeLocation & loc, WaitUntilStmt::ClauseNode * currNode, int & idx, GenLeafExpr genLeaf ) {
-    Expr * leftExpr, * rightExpr;
-    switch (currNode->op) {
-        case WaitUntilStmt::ClauseNode::AND:
-            leftExpr = genPredExpr( loc, currNode->left, idx, genLeaf );
-            rightExpr = genPredExpr( loc, currNode->right, idx, genLeaf );
-            return new LogicalExpr( loc, 
-                new CastExpr( loc, leftExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
-                new CastExpr( loc, rightExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ), 
-                LogicalFlag::AndExpr 
-            );
-            break;
-        case WaitUntilStmt::ClauseNode::OR:
-            leftExpr = genPredExpr( loc, currNode->left, idx, genLeaf );
-            rightExpr = genPredExpr( loc, currNode->right, idx, genLeaf );
-            return new LogicalExpr( loc,
-                new CastExpr( loc, leftExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
-                new CastExpr( loc, rightExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ), 
-                LogicalFlag::OrExpr );
-            break;
-        case WaitUntilStmt::ClauseNode::LEAF:
-            return genLeaf( loc, idx );
-            break;
-        default:
-            assertf(false, "Unreachable waituntil clause node type. How did you get here???");\
-            return nullptr;
-            break;
-    }
-    return nullptr;
+	Expr * leftExpr, * rightExpr;
+	switch (currNode->op) {
+		case WaitUntilStmt::ClauseNode::AND:
+			leftExpr = genPredExpr( loc, currNode->left, idx, genLeaf );
+			rightExpr = genPredExpr( loc, currNode->right, idx, genLeaf );
+			return new LogicalExpr( loc,
+				new CastExpr( loc, leftExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
+				new CastExpr( loc, rightExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
+				LogicalFlag::AndExpr
+			);
+			break;
+		case WaitUntilStmt::ClauseNode::OR:
+			leftExpr = genPredExpr( loc, currNode->left, idx, genLeaf );
+			rightExpr = genPredExpr( loc, currNode->right, idx, genLeaf );
+			return new LogicalExpr( loc,
+				new CastExpr( loc, leftExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
+				new CastExpr( loc, rightExpr, new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast ),
+				LogicalFlag::OrExpr );
+			break;
+		case WaitUntilStmt::ClauseNode::LEAF:
+			return genLeaf( loc, idx );
+			break;
+		default:
+			assertf(false, "Unreachable waituntil clause node type. How did you get here???");\
+			return nullptr;
+			break;
+	}
+	return nullptr;
 }
 
@@ -526,19 +526,19 @@
 /* Ex:
 {
-    waituntil( A ){ doA(); } 
-    or waituntil( B ){ doB(); } 
-    and waituntil( C ) { doC(); }
+	waituntil( A ){ doA(); }
+	or waituntil( B ){ doB(); }
+	and waituntil( C ) { doC(); }
 }
 generates =>
 static inline bool is_full_sat_1( int * clause_statuses ) {
-    return clause_statuses[0] 
-        || clause_statuses[1]
-        && clause_statuses[2];
+	return clause_statuses[0]
+		|| clause_statuses[1]
+		&& clause_statuses[2];
 }
 
 static inline bool is_done_sat_1( int * clause_statuses ) {
-    return has_run(clause_statuses[0])
-        || has_run(clause_statuses[1])
-        && has_run(clause_statuses[2]);
+	return has_run(clause_statuses[0])
+		|| has_run(clause_statuses[1])
+		&& has_run(clause_statuses[2]);
 }
 */
@@ -546,36 +546,36 @@
 // predName and genLeaf determine if this generates an is_done or an is_full predicate
 FunctionDecl * buildPredicate( const WaitUntilStmt * stmt, GenLeafExpr genLeaf, string & predName ) {
-    int arrIdx = 0;
-    const CodeLocation & loc = stmt->location;
-    CompoundStmt * body = new CompoundStmt( loc );
-    body->push_back( new ReturnStmt( loc, genPredExpr( loc,  stmt->predicateTree, arrIdx, genLeaf ) ) );
-
-    return new FunctionDecl( loc,
-        predName,
-        {
-            new ObjectDecl( loc,
-                "clause_statuses",
-                new PointerType( new BasicType( BasicKind::LongUnsignedInt ) )
-            )
-        },
-        {
-            new ObjectDecl( loc,
-                "sat_ret",
-                new BasicType( BasicKind::Bool )
-            )
-        },
-        body,               // body
-        { Storage::Static },    // storage
-        Linkage::Cforall,       // linkage
-        {},                     // attributes
-        { Function::Inline }
-    );
+	int arrIdx = 0;
+	const CodeLocation & loc = stmt->location;
+	CompoundStmt * body = new CompoundStmt( loc );
+	body->push_back( new ReturnStmt( loc, genPredExpr( loc,  stmt->predicateTree, arrIdx, genLeaf ) ) );
+
+	return new FunctionDecl( loc,
+		predName,
+		{
+			new ObjectDecl( loc,
+				"clause_statuses",
+				new PointerType( new BasicType( BasicKind::LongUnsignedInt ) )
+			)
+		},
+		{
+			new ObjectDecl( loc,
+				"sat_ret",
+				new BasicType( BasicKind::Bool )
+			)
+		},
+		body,               // body
+		{ Storage::Static },    // storage
+		Linkage::Cforall,       // linkage
+		{},                     // attributes
+		{ Function::Inline }
+	);
 }
 
 // Creates is_done and is_full predicates
 void GenerateWaitUntilCore::addPredicates( const WaitUntilStmt * stmt, string & satName, string & runName ) {
-    if ( !stmt->else_stmt || stmt->else_cond ) // don't need SAT predicate when else variation with no else_cond
-        satFns.push_back( Concurrency::buildPredicate( stmt, genSatExpr, satName ) ); 
-    satFns.push_back( Concurrency::buildPredicate( stmt, genRunExpr, runName ) );
+	if ( !stmt->else_stmt || stmt->else_cond ) // don't need SAT predicate when else variation with no else_cond
+		satFns.push_back( Concurrency::buildPredicate( stmt, genSatExpr, satName ) );
+	satFns.push_back( Concurrency::buildPredicate( stmt, genRunExpr, runName ) );
 }
 
@@ -585,232 +585,232 @@
 //      register_select(A, clause1);
 // }
-void GenerateWaitUntilCore::setUpClause( const WhenClause * clause, ClauseData * data, string & pCountName, CompoundStmt * body ) {    
-    CompoundStmt * currBody = body;
-    const CodeLocation & loc = clause->location;
-
-    // If we have a when_cond make the initialization conditional
-    if ( clause->when_cond )
-        currBody = new CompoundStmt( loc );
-
-    // Generates: setup_clause( clause1, &clause_statuses[0], &park_counter );
-    currBody->push_back( new ExprStmt( loc,
-        new UntypedExpr ( loc,
-            new NameExpr( loc, "setup_clause" ),
-            {
-                new NameExpr( loc, data->nodeName ),
-                new AddressExpr( loc, genArrAccessExpr( loc, data->index, data->statusName ) ),
-                new AddressExpr( loc, new NameExpr( loc, pCountName ) )
-            }
-        )
-    ));
-
-    // Generates: register_select(A, clause1);
-    currBody->push_back( new ExprStmt( loc, genSelectTraitCall( clause, data, "register_select" ) ) );
-
-    // generates: if ( when_cond ) { ... currBody ... }
-    if ( clause->when_cond )
-        body->push_back( 
-            new IfStmt( loc,
-                new NameExpr( loc, data->whenName ),
-                currBody
-            )
-        );
+void GenerateWaitUntilCore::setUpClause( const WhenClause * clause, ClauseData * data, string & pCountName, CompoundStmt * body ) {
+	CompoundStmt * currBody = body;
+	const CodeLocation & loc = clause->location;
+
+	// If we have a when_cond make the initialization conditional
+	if ( clause->when_cond )
+		currBody = new CompoundStmt( loc );
+
+	// Generates: setup_clause( clause1, &clause_statuses[0], &park_counter );
+	currBody->push_back( new ExprStmt( loc,
+		new UntypedExpr ( loc,
+			new NameExpr( loc, "setup_clause" ),
+			{
+				new NameExpr( loc, data->nodeName ),
+				new AddressExpr( loc, genArrAccessExpr( loc, data->index, data->statusName ) ),
+				new AddressExpr( loc, new NameExpr( loc, pCountName ) )
+			}
+		)
+	));
+
+	// Generates: register_select(A, clause1);
+	currBody->push_back( new ExprStmt( loc, genSelectTraitCall( clause, data, "register_select" ) ) );
+
+	// generates: if ( when_cond ) { ... currBody ... }
+	if ( clause->when_cond )
+		body->push_back(
+			new IfStmt( loc,
+				new NameExpr( loc, data->whenName ),
+				currBody
+			)
+		);
 }
 
 // Used to generate a call to one of the select trait routines
 Expr * GenerateWaitUntilCore::genSelectTraitCall( const WhenClause * clause, const ClauseData * data, string fnName ) {
-    const CodeLocation & loc = clause->location;
-    return new UntypedExpr ( loc,
-        new NameExpr( loc, fnName ),
-        {
-            new NameExpr( loc, data->targetName ),
-            new NameExpr( loc, data->nodeName )
-        }
-    );
+	const CodeLocation & loc = clause->location;
+	return new UntypedExpr ( loc,
+		new NameExpr( loc, fnName ),
+		{
+			new NameExpr( loc, data->targetName ),
+			new NameExpr( loc, data->nodeName )
+		}
+	);
 }
 
 // Generates:
-/* on_selected( target_1, node_1 ); ... corresponding body of target_1 ... 
+/* on_selected( target_1, node_1 ); ... corresponding body of target_1 ...
 */
 CompoundStmt * GenerateWaitUntilCore::genStmtBlock( const WhenClause * clause, const ClauseData * data ) {
-    const CodeLocation & cLoc = clause->location;
-    return new CompoundStmt( cLoc,
-        {
-            new IfStmt( cLoc,
-                genSelectTraitCall( clause, data, "on_selected" ),
-                ast::deepCopy( clause->stmt )
-            )
-        }
-    );
+	const CodeLocation & cLoc = clause->location;
+	return new CompoundStmt( cLoc,
+		{
+			new IfStmt( cLoc,
+				genSelectTraitCall( clause, data, "on_selected" ),
+				ast::deepCopy( clause->stmt )
+			)
+		}
+	);
 }
 
 // this routine generates and returns the following
 /*for ( int i = 0; i < numClauses; i++ ) {
-    if ( predName(clause_statuses) ) break;
-    if (clause_statuses[i] == __SELECT_SAT) {
-        switch (i) {
-            case 0:
-                try {
-                    on_selected( target1, clause1 );
-                    dotarget1stmt();
-                }
-                finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
-                break;
-            ...
-            case N:
-                ...
-                break;
-        }
-    }
+	if ( predName(clause_statuses) ) break;
+	if (clause_statuses[i] == __SELECT_SAT) {
+		switch (i) {
+			case 0:
+				try {
+				    on_selected( target1, clause1 );
+				    dotarget1stmt();
+				}
+				finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
+				break;
+			...
+			case N:
+				...
+				break;
+		}
+	}
 }*/
 CompoundStmt * GenerateWaitUntilCore::genStatusCheckFor( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, string & predName ) {
-    CompoundStmt * ifBody = new CompoundStmt( stmt->location );
-    const CodeLocation & loc = stmt->location;
-
-    string switchLabel = namer_label.newName();
-
-    /* generates:
-    switch (i) {
-        case 0:
-            try {
-                on_selected( target1, clause1 );
-                dotarget1stmt();
-            }
-            finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
-            break;
-            ...
-        case N:
-            ...
-            break;
-    }*/
-    std::vector<ptr<CaseClause>> switchCases;
-    int idx = 0;
-    for ( const auto & clause: stmt->clauses ) {
-        const CodeLocation & cLoc = clause->location;
-        switchCases.push_back(
-            new CaseClause( cLoc,
-                ConstantExpr::from_int( cLoc, idx ),
-                {
-                    new CompoundStmt( cLoc,
-                        {
-                            new ast::TryStmt( cLoc,
-                                genStmtBlock( clause, clauseData.at(idx) ),
-                                {},
-                                new ast::FinallyClause( cLoc, 
-                                    new CompoundStmt( cLoc,
-                                        {
-                                            new ExprStmt( loc,
-                                                new UntypedExpr ( loc,
-                                                    new NameExpr( loc, "?=?" ),
-                                                    {
-                                                        new UntypedExpr ( loc, 
-                                                            new NameExpr( loc, "?[?]" ),
-                                                            {
-                                                                new NameExpr( loc, clauseData.at(0)->statusName ),
-                                                                new NameExpr( loc, idxName )
-                                                            }
-                                                        ),
-                                                        new NameExpr( loc, "__SELECT_RUN" )
-                                                    }
-                                                )
-                                            ),
-                                            new ExprStmt( loc, genSelectTraitCall( clause, clauseData.at(idx), "unregister_select" ) )
-                                        }
-                                    )
-                                )
-                            ),
-                            new BranchStmt( cLoc, BranchStmt::Kind::Break, Label( cLoc, switchLabel ) )
-                        }
-                    )
-                }
-            )
-        );
-        idx++;
-    }
-
-    ifBody->push_back(
-        new SwitchStmt( loc,
-            new NameExpr( loc, idxName ),
-            std::move( switchCases ),
-            { Label( loc, switchLabel ) }
-        )
-    );
-
-    // gens:
-    // if (clause_statuses[i] == __SELECT_SAT) {
-    //      ... ifBody  ...
-    // }
-    IfStmt * ifSwitch = new IfStmt( loc,
-        new UntypedExpr ( loc,
-            new NameExpr( loc, "?==?" ),
-            {
-                new UntypedExpr ( loc, 
-                    new NameExpr( loc, "?[?]" ),
-                    {
-                        new NameExpr( loc, clauseData.at(0)->statusName ),
-                        new NameExpr( loc, idxName )
-                    }
-                ),
-                new NameExpr( loc, "__SELECT_SAT" )
-            }
-        ),      // condition
-        ifBody  // body
-    );
-
-    string forLabel = namer_label.newName();
-
-    // we hoist init here so that this pass can happen after hoistdecls pass
-    return new CompoundStmt( loc,
-        {
-            new DeclStmt( loc,
-                new ObjectDecl( loc,
-                    idxName,
-                    new BasicType( BasicKind::SignedInt ),
-                    new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
-                )
-            ),
-            new ForStmt( loc,
-                {},  // inits
-                new UntypedExpr ( loc,
-                    new NameExpr( loc, "?<?" ),
-                    {
-                        new NameExpr( loc, idxName ),
-                        ConstantExpr::from_int( loc, stmt->clauses.size() )
-                    }
-                ),  // cond
-                new UntypedExpr ( loc,
-                    new NameExpr( loc, "?++" ),
-                    { new NameExpr( loc, idxName ) }
-                ),  // inc
-                new CompoundStmt( loc,
-                    {
-                        new IfStmt( loc,
-                            new UntypedExpr ( loc,
-                                new NameExpr( loc, predName ),
-                                { new NameExpr( loc, clauseData.at(0)->statusName ) }
-                            ),
-                            new BranchStmt( loc, BranchStmt::Kind::Break, Label( loc, forLabel ) )
-                        ),
-                        ifSwitch
-                    }
-                ),   // body
-                { Label( loc, forLabel ) }
-            )
-        }
-    );
+	CompoundStmt * ifBody = new CompoundStmt( stmt->location );
+	const CodeLocation & loc = stmt->location;
+
+	string switchLabel = namer_label.newName();
+
+	/* generates:
+	switch (i) {
+		case 0:
+			try {
+				on_selected( target1, clause1 );
+				dotarget1stmt();
+			}
+			finally { clause_statuses[i] = __SELECT_RUN; unregister_select(target1, clause1); }
+			break;
+			...
+		case N:
+			...
+			break;
+	}*/
+	std::vector<ptr<CaseClause>> switchCases;
+	int idx = 0;
+	for ( const auto & clause: stmt->clauses ) {
+		const CodeLocation & cLoc = clause->location;
+		switchCases.push_back(
+			new CaseClause( cLoc,
+				ConstantExpr::from_int( cLoc, idx ),
+				{
+				    new CompoundStmt( cLoc,
+				        {
+				            new ast::TryStmt( cLoc,
+				                genStmtBlock( clause, clauseData.at(idx) ),
+				                {},
+				                new ast::FinallyClause( cLoc,
+				                    new CompoundStmt( cLoc,
+				                        {
+				                            new ExprStmt( loc,
+				                                new UntypedExpr ( loc,
+				                                    new NameExpr( loc, "?=?" ),
+				                                    {
+				                                        new UntypedExpr ( loc,
+				                                            new NameExpr( loc, "?[?]" ),
+				                                            {
+				                                                new NameExpr( loc, clauseData.at(0)->statusName ),
+				                                                new NameExpr( loc, idxName )
+				                                            }
+				                                        ),
+				                                        new NameExpr( loc, "__SELECT_RUN" )
+				                                    }
+				                                )
+				                            ),
+				                            new ExprStmt( loc, genSelectTraitCall( clause, clauseData.at(idx), "unregister_select" ) )
+				                        }
+				                    )
+				                )
+				            ),
+				            new BranchStmt( cLoc, BranchStmt::Kind::Break, Label( cLoc, switchLabel ) )
+				        }
+				    )
+				}
+			)
+		);
+		idx++;
+	}
+
+	ifBody->push_back(
+		new SwitchStmt( loc,
+			new NameExpr( loc, idxName ),
+			std::move( switchCases ),
+			{ Label( loc, switchLabel ) }
+		)
+	);
+
+	// gens:
+	// if (clause_statuses[i] == __SELECT_SAT) {
+	//      ... ifBody  ...
+	// }
+	IfStmt * ifSwitch = new IfStmt( loc,
+		new UntypedExpr ( loc,
+			new NameExpr( loc, "?==?" ),
+			{
+				new UntypedExpr ( loc,
+				    new NameExpr( loc, "?[?]" ),
+				    {
+				        new NameExpr( loc, clauseData.at(0)->statusName ),
+				        new NameExpr( loc, idxName )
+				    }
+				),
+				new NameExpr( loc, "__SELECT_SAT" )
+			}
+		),      // condition
+		ifBody  // body
+	);
+
+	string forLabel = namer_label.newName();
+
+	// we hoist init here so that this pass can happen after hoistdecls pass
+	return new CompoundStmt( loc,
+		{
+			new DeclStmt( loc,
+				new ObjectDecl( loc,
+				    idxName,
+				    new BasicType( BasicKind::SignedInt ),
+				    new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
+				)
+			),
+			new ForStmt( loc,
+				{},  // inits
+				new UntypedExpr ( loc,
+				    new NameExpr( loc, "?<?" ),
+				    {
+				        new NameExpr( loc, idxName ),
+				        ConstantExpr::from_int( loc, stmt->clauses.size() )
+				    }
+				),  // cond
+				new UntypedExpr ( loc,
+				    new NameExpr( loc, "?++" ),
+				    { new NameExpr( loc, idxName ) }
+				),  // inc
+				new CompoundStmt( loc,
+				    {
+				        new IfStmt( loc,
+				            new UntypedExpr ( loc,
+				                new NameExpr( loc, predName ),
+				                { new NameExpr( loc, clauseData.at(0)->statusName ) }
+				            ),
+				            new BranchStmt( loc, BranchStmt::Kind::Break, Label( loc, forLabel ) )
+				        ),
+				        ifSwitch
+				    }
+				),   // body
+				{ Label( loc, forLabel ) }
+			)
+		}
+	);
 }
 
 // Generates: !is_full_sat_n() / !is_run_sat_n()
 Expr * genNotSatExpr( const WaitUntilStmt * stmt, string & satName, string & arrName ) {
-    const CodeLocation & loc = stmt->location;
-    return new UntypedExpr ( loc,
-        new NameExpr( loc, "!?" ),
-        {
-            new UntypedExpr ( loc,
-                new NameExpr( loc, satName ),
-                { new NameExpr( loc, arrName ) }
-            )
-        }
-    );
+	const CodeLocation & loc = stmt->location;
+	return new UntypedExpr ( loc,
+		new NameExpr( loc, "!?" ),
+		{
+			new UntypedExpr ( loc,
+				new NameExpr( loc, satName ),
+				{ new NameExpr( loc, arrName ) }
+			)
+		}
+	);
 }
 
@@ -819,40 +819,40 @@
 // If not enough have run to satisfy predicate after one pass then the else is run
 Stmt * GenerateWaitUntilCore::genElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, vector<ClauseData *> & clauseData ) {
-    return new CompoundStmt( stmt->else_stmt->location,
-        {
-            genStatusCheckFor( stmt, clauseData, runName ),
-            new IfStmt( stmt->else_stmt->location,
-                genNotSatExpr( stmt, runName, arrName ),
-                ast::deepCopy( stmt->else_stmt )
-            )
-        }
-    );
+	return new CompoundStmt( stmt->else_stmt->location,
+		{
+			genStatusCheckFor( stmt, clauseData, runName ),
+			new IfStmt( stmt->else_stmt->location,
+				genNotSatExpr( stmt, runName, arrName ),
+				ast::deepCopy( stmt->else_stmt )
+			)
+		}
+	);
 }
 
 Stmt * GenerateWaitUntilCore::genNoElseClauseBranch( const WaitUntilStmt * stmt, string & runName, string & arrName, string & pCountName, vector<ClauseData *> & clauseData ) {
-    CompoundStmt * whileBody = new CompoundStmt( stmt->location );
-    const CodeLocation & loc = stmt->location;
-
-    // generates: __CFA_maybe_park( &park_counter );
-    whileBody->push_back(
-        new ExprStmt( loc,
-            new UntypedExpr ( loc,
-                new NameExpr( loc, "__CFA_maybe_park" ),
-                { new AddressExpr( loc, new NameExpr( loc, pCountName ) ) }
-            )
-        )
-    );
-
-    whileBody->push_back( genStatusCheckFor( stmt, clauseData, runName ) );
-
-    return new CompoundStmt( loc,
-        {
-            new WhileDoStmt( loc,
-                genNotSatExpr( stmt, runName, arrName ),
-                whileBody,  // body
-                {}          // no inits
-            )
-        }
-    );
+	CompoundStmt * whileBody = new CompoundStmt( stmt->location );
+	const CodeLocation & loc = stmt->location;
+
+	// generates: __CFA_maybe_park( &park_counter );
+	whileBody->push_back(
+		new ExprStmt( loc,
+			new UntypedExpr ( loc,
+				new NameExpr( loc, "__CFA_maybe_park" ),
+				{ new AddressExpr( loc, new NameExpr( loc, pCountName ) ) }
+			)
+		)
+	);
+
+	whileBody->push_back( genStatusCheckFor( stmt, clauseData, runName ) );
+
+	return new CompoundStmt( loc,
+		{
+			new WhileDoStmt( loc,
+				genNotSatExpr( stmt, runName, arrName ),
+				whileBody,  // body
+				{}          // no inits
+			)
+		}
+	);
 }
 
@@ -862,63 +862,63 @@
 // select_node clause1;
 void GenerateWaitUntilCore::genClauseInits( const WaitUntilStmt * stmt, vector<ClauseData *> & clauseData, CompoundStmt * body, string & statusName, string & elseWhenName ) {
-    ClauseData * currClause;
-    for ( vector<ClauseData*>::size_type i = 0; i < stmt->clauses.size(); i++ ) {
-        currClause = new ClauseData( i, statusName );
-        currClause->nodeName = namer_node.newName();
-        currClause->targetName = namer_target.newName();
-        currClause->whenName = namer_when.newName();
-        clauseData.push_back(currClause);
-        const CodeLocation & cLoc = stmt->clauses.at(i)->location;
-
-        // typeof(target) & __clause_target_0 = target;
-        body->push_back(
-            new DeclStmt( cLoc,
-                new ObjectDecl( cLoc,
-                    currClause->targetName,
-                    new ReferenceType( 
-                        new TypeofType( new UntypedExpr( cLoc,
-                            new NameExpr( cLoc, "__CFA_select_get_type" ),
-                            { ast::deepCopy( stmt->clauses.at(i)->target ) }
-                        ))
-                    ),
-                    new SingleInit( cLoc, ast::deepCopy( stmt->clauses.at(i)->target ) )
-                )
-            )
-        );
-
-        // bool __when_cond_0 = when_cond; // only generated if when_cond defined
-        if ( stmt->clauses.at(i)->when_cond )
-            body->push_back(
-                new DeclStmt( cLoc,
-                    new ObjectDecl( cLoc,
-                        currClause->whenName,
-                        new BasicType( BasicKind::Bool ),
-                        new SingleInit( cLoc, ast::deepCopy( stmt->clauses.at(i)->when_cond ) )
-                    )
-                )
-            );
-        
-        // select_node clause1;
-        body->push_back(
-            new DeclStmt( cLoc,
-                new ObjectDecl( cLoc,
-                    currClause->nodeName,
-                    new StructInstType( selectNodeDecl )
-                )
-            )
-        );
-    }
-
-    if ( stmt->else_stmt && stmt->else_cond ) {
-        body->push_back(
-            new DeclStmt( stmt->else_cond->location,
-                new ObjectDecl( stmt->else_cond->location,
-                    elseWhenName,
-                    new BasicType( BasicKind::Bool ),
-                    new SingleInit( stmt->else_cond->location, ast::deepCopy( stmt->else_cond ) )
-                )
-            )
-        );
-    }
+	ClauseData * currClause;
+	for ( vector<ClauseData*>::size_type i = 0; i < stmt->clauses.size(); i++ ) {
+		currClause = new ClauseData( i, statusName );
+		currClause->nodeName = namer_node.newName();
+		currClause->targetName = namer_target.newName();
+		currClause->whenName = namer_when.newName();
+		clauseData.push_back(currClause);
+		const CodeLocation & cLoc = stmt->clauses.at(i)->location;
+
+		// typeof(target) & __clause_target_0 = target;
+		body->push_back(
+			new DeclStmt( cLoc,
+				new ObjectDecl( cLoc,
+				    currClause->targetName,
+				    new ReferenceType(
+				        new TypeofType( new UntypedExpr( cLoc,
+				            new NameExpr( cLoc, "__CFA_select_get_type" ),
+				            { ast::deepCopy( stmt->clauses.at(i)->target ) }
+				        ))
+				    ),
+				    new SingleInit( cLoc, ast::deepCopy( stmt->clauses.at(i)->target ) )
+				)
+			)
+		);
+
+		// bool __when_cond_0 = when_cond; // only generated if when_cond defined
+		if ( stmt->clauses.at(i)->when_cond )
+			body->push_back(
+				new DeclStmt( cLoc,
+				    new ObjectDecl( cLoc,
+				        currClause->whenName,
+				        new BasicType( BasicKind::Bool ),
+				        new SingleInit( cLoc, ast::deepCopy( stmt->clauses.at(i)->when_cond ) )
+				    )
+				)
+			);
+
+		// select_node clause1;
+		body->push_back(
+			new DeclStmt( cLoc,
+				new ObjectDecl( cLoc,
+				    currClause->nodeName,
+				    new StructInstType( selectNodeDecl )
+				)
+			)
+		);
+	}
+
+	if ( stmt->else_stmt && stmt->else_cond ) {
+		body->push_back(
+			new DeclStmt( stmt->else_cond->location,
+				new ObjectDecl( stmt->else_cond->location,
+				    elseWhenName,
+				    new BasicType( BasicKind::Bool ),
+				    new SingleInit( stmt->else_cond->location, ast::deepCopy( stmt->else_cond ) )
+				)
+			)
+		);
+	}
 }
 
@@ -929,27 +929,27 @@
 */
 Stmt * GenerateWaitUntilCore::buildOrCaseSwitch( const WaitUntilStmt * stmt, string & statusName, vector<ClauseData *> & data ) {
-    const CodeLocation & loc = stmt->location;
-
-    IfStmt * outerIf = nullptr;
+	const CodeLocation & loc = stmt->location;
+
+	IfStmt * outerIf = nullptr;
 	IfStmt * lastIf = nullptr;
 
 	//adds an if/elif clause for each select clause address to run the corresponding clause stmt
 	for ( long unsigned int i = 0; i < data.size(); i++ ) {
-        const CodeLocation & cLoc = stmt->clauses.at(i)->location;
+		const CodeLocation & cLoc = stmt->clauses.at(i)->location;
 
 		IfStmt * currIf = new IfStmt( cLoc,
-			new UntypedExpr( cLoc, 
-                new NameExpr( cLoc, "?==?" ), 
-                {
-                    new NameExpr( cLoc, statusName ),
-                    new CastExpr( cLoc, 
-                        new AddressExpr( cLoc, new NameExpr( cLoc, data.at(i)->nodeName ) ),
-                        new BasicType( BasicKind::LongUnsignedInt ), GeneratedFlag::ExplicitCast 
-                    )
-                }
-            ),
-            genStmtBlock( stmt->clauses.at(i), data.at(i) )
-		);
-		
+			new UntypedExpr( cLoc,
+				new NameExpr( cLoc, "?==?" ),
+				{
+				    new NameExpr( cLoc, statusName ),
+				    new CastExpr( cLoc,
+				        new AddressExpr( cLoc, new NameExpr( cLoc, data.at(i)->nodeName ) ),
+				        new BasicType( BasicKind::LongUnsignedInt ), GeneratedFlag::ExplicitCast
+				    )
+				}
+			),
+			genStmtBlock( stmt->clauses.at(i), data.at(i) )
+		);
+
 		if ( i == 0 ) {
 			outerIf = currIf;
@@ -962,92 +962,92 @@
 	}
 
-    return new CompoundStmt( loc,
-        {
-            new ExprStmt( loc, new UntypedExpr( loc, new NameExpr( loc, "park" ) ) ),
-            outerIf
-        }
-    );
+	return new CompoundStmt( loc,
+		{
+			new ExprStmt( loc, new UntypedExpr( loc, new NameExpr( loc, "park" ) ) ),
+			outerIf
+		}
+	);
 }
 
 Stmt * GenerateWaitUntilCore::recursiveOrIfGen( const WaitUntilStmt * stmt, vector<ClauseData *> & data, vector<ClauseData*>::size_type idx, string & elseWhenName ) {
-    if ( idx == data.size() ) {   // base case, gen last else
-        const CodeLocation & cLoc = stmt->else_stmt->location;
-        if ( !stmt->else_stmt ) // normal non-else gen
-            return buildOrCaseSwitch( stmt, data.at(0)->statusName, data );
-
-        Expr * raceFnCall = new UntypedExpr( stmt->location,
-            new NameExpr( stmt->location, "__select_node_else_race" ),
-            { new NameExpr( stmt->location, data.at(0)->nodeName ) }
-        );
-
-        if ( stmt->else_stmt && stmt->else_cond ) { // return else conditional on both when and race
-            return new IfStmt( cLoc,
-                new LogicalExpr( cLoc,
-                    new CastExpr( cLoc,
-                        new NameExpr( cLoc, elseWhenName ),
-                        new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                    ),
-                    new CastExpr( cLoc,
-                        raceFnCall,
-                        new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                    ),
-                    LogicalFlag::AndExpr
-                ),
-                ast::deepCopy( stmt->else_stmt ),
-                buildOrCaseSwitch( stmt, data.at(0)->statusName, data )
-            );
-        }
-
-        // return else conditional on race
-        return new IfStmt( stmt->else_stmt->location,
-            raceFnCall,
-            ast::deepCopy( stmt->else_stmt ),
-            buildOrCaseSwitch( stmt, data.at(0)->statusName, data )
-        );
-    }
-    const CodeLocation & cLoc = stmt->clauses.at(idx)->location;
-
-    Expr * baseCond = genSelectTraitCall( stmt->clauses.at(idx), data.at(idx), "register_select" );
-    Expr * ifCond;
-
-    // If we have a when_cond make the register call conditional on it
-    if ( stmt->clauses.at(idx)->when_cond ) {
-        ifCond = new LogicalExpr( cLoc,
-            new CastExpr( cLoc,
-                new NameExpr( cLoc, data.at(idx)->whenName ), 
-                new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-            ),
-            new CastExpr( cLoc,
-                baseCond,
-                new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-            ),
-            LogicalFlag::AndExpr
-        );
-    } else ifCond = baseCond;
-
-    return new CompoundStmt( cLoc,
-        {   // gens: setup_clause( clause1, &status, 0p );
-            new ExprStmt( cLoc,
-                new UntypedExpr ( cLoc,
-                    new NameExpr( cLoc, "setup_clause" ),
-                    {
-                        new NameExpr( cLoc, data.at(idx)->nodeName ),
-                        new AddressExpr( cLoc, new NameExpr( cLoc, data.at(idx)->statusName ) ),
-                        ConstantExpr::null( cLoc, new PointerType( new BasicType( BasicKind::SignedInt ) ) )
-                    }
-                )
-            ),
-            // gens: if (__when_cond && register_select()) { clause body } else { ... recursiveOrIfGen ... }
-            new IfStmt( cLoc,
-                ifCond,
-                genStmtBlock( stmt->clauses.at(idx), data.at(idx) ),
-                recursiveOrIfGen( stmt, data, idx + 1, elseWhenName )
-            )
-        }
-    );
+	if ( idx == data.size() ) {   // base case, gen last else
+		const CodeLocation & cLoc = stmt->else_stmt->location;
+		if ( !stmt->else_stmt ) // normal non-else gen
+			return buildOrCaseSwitch( stmt, data.at(0)->statusName, data );
+
+		Expr * raceFnCall = new UntypedExpr( stmt->location,
+			new NameExpr( stmt->location, "__select_node_else_race" ),
+			{ new NameExpr( stmt->location, data.at(0)->nodeName ) }
+		);
+
+		if ( stmt->else_stmt && stmt->else_cond ) { // return else conditional on both when and race
+			return new IfStmt( cLoc,
+				new LogicalExpr( cLoc,
+				    new CastExpr( cLoc,
+				        new NameExpr( cLoc, elseWhenName ),
+				        new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				    ),
+				    new CastExpr( cLoc,
+				        raceFnCall,
+				        new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				    ),
+				    LogicalFlag::AndExpr
+				),
+				ast::deepCopy( stmt->else_stmt ),
+				buildOrCaseSwitch( stmt, data.at(0)->statusName, data )
+			);
+		}
+
+		// return else conditional on race
+		return new IfStmt( stmt->else_stmt->location,
+			raceFnCall,
+			ast::deepCopy( stmt->else_stmt ),
+			buildOrCaseSwitch( stmt, data.at(0)->statusName, data )
+		);
+	}
+	const CodeLocation & cLoc = stmt->clauses.at(idx)->location;
+
+	Expr * baseCond = genSelectTraitCall( stmt->clauses.at(idx), data.at(idx), "register_select" );
+	Expr * ifCond;
+
+	// If we have a when_cond make the register call conditional on it
+	if ( stmt->clauses.at(idx)->when_cond ) {
+		ifCond = new LogicalExpr( cLoc,
+			new CastExpr( cLoc,
+				new NameExpr( cLoc, data.at(idx)->whenName ),
+				new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+			),
+			new CastExpr( cLoc,
+				baseCond,
+				new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+			),
+			LogicalFlag::AndExpr
+		);
+	} else ifCond = baseCond;
+
+	return new CompoundStmt( cLoc,
+		{   // gens: setup_clause( clause1, &status, 0p );
+			new ExprStmt( cLoc,
+				new UntypedExpr ( cLoc,
+				    new NameExpr( cLoc, "setup_clause" ),
+				    {
+				        new NameExpr( cLoc, data.at(idx)->nodeName ),
+				        new AddressExpr( cLoc, new NameExpr( cLoc, data.at(idx)->statusName ) ),
+				        ConstantExpr::null( cLoc, new PointerType( new BasicType( BasicKind::SignedInt ) ) )
+				    }
+				)
+			),
+			// gens: if (__when_cond && register_select()) { clause body } else { ... recursiveOrIfGen ... }
+			new IfStmt( cLoc,
+				ifCond,
+				genStmtBlock( stmt->clauses.at(idx), data.at(idx) ),
+				recursiveOrIfGen( stmt, data, idx + 1, elseWhenName )
+			)
+		}
+	);
 }
 
 // This gens the special case of an all OR waituntil:
-/* 
+/*
 int status = 0;
 
@@ -1058,340 +1058,340 @@
 
 try {
-    setup_clause( clause1, &status, 0p );
-    if ( __when_cond_0 && register_select( 1 ) ) {
-        ... clause 1 body ...
-    } else {
-        ... recursively gen for each of n clauses ...
-        setup_clause( clausen, &status, 0p );
-        if ( __when_cond_n-1 && register_select( n ) ) {
-            ... clause n body ...
-        } else {
-            if ( else_when ) ... else clause body ...
-            else {
-                park();
-
-                // after winning the race and before unpark() clause_status is set to be the winning clause index + 1 
-                if ( clause_status == &clause1) ... clause 1 body ...
-                ...
-                elif ( clause_status == &clausen ) ... clause n body ...
-            }
-        }
-    }
-}
-finally { 
-    if ( __when_cond_1 && clause1.status != 0p) unregister_select( 1 ); // if registered unregister
-    ...
-    if ( __when_cond_n && clausen.status != 0p) unregister_select( n );
+	setup_clause( clause1, &status, 0p );
+	if ( __when_cond_0 && register_select( 1 ) ) {
+		... clause 1 body ...
+	} else {
+		... recursively gen for each of n clauses ...
+		setup_clause( clausen, &status, 0p );
+		if ( __when_cond_n-1 && register_select( n ) ) {
+			... clause n body ...
+		} else {
+			if ( else_when ) ... else clause body ...
+			else {
+				park();
+
+				// after winning the race and before unpark() clause_status is set to be the winning clause index + 1
+				if ( clause_status == &clause1) ... clause 1 body ...
+				...
+				elif ( clause_status == &clausen ) ... clause n body ...
+			}
+		}
+	}
+}
+finally {
+	if ( __when_cond_1 && clause1.status != 0p) unregister_select( 1 ); // if registered unregister
+	...
+	if ( __when_cond_n && clausen.status != 0p) unregister_select( n );
 }
 */
 Stmt * GenerateWaitUntilCore::genAllOr( const WaitUntilStmt * stmt ) {
-    const CodeLocation & loc = stmt->location;
-    string statusName = namer_status.newName();
-    string elseWhenName = namer_when.newName();
-    int numClauses = stmt->clauses.size();
-    CompoundStmt * body = new CompoundStmt( stmt->location );
-
-    // Generates: unsigned long int status = 0;
-    body->push_back( new DeclStmt( loc,
-        new ObjectDecl( loc,
-            statusName,
-            new BasicType( BasicKind::LongUnsignedInt ),
-            new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
-        )
-    ));
-
-    vector<ClauseData *> clauseData;
-    genClauseInits( stmt, clauseData, body, statusName, elseWhenName );
-
-    vector<int> whenIndices; // track which clauses have whens
-
-    CompoundStmt * unregisters = new CompoundStmt( loc );
-    Expr * ifCond;
-    for ( int i = 0; i < numClauses; i++ ) {
-        const CodeLocation & cLoc = stmt->clauses.at(i)->location;
-        // Gens: node.status != 0p
-        UntypedExpr * statusPtrCheck = new UntypedExpr( cLoc, 
-            new NameExpr( cLoc, "?!=?" ), 
-            {
-                ConstantExpr::null( cLoc, new PointerType( new BasicType( BasicKind::LongUnsignedInt ) ) ),
-                new UntypedExpr( cLoc, 
-                    new NameExpr( cLoc, "__get_clause_status" ), 
-                    { new NameExpr( cLoc, clauseData.at(i)->nodeName ) } 
-                ) 
-            }
-        );
-
-        // If we have a when_cond make the unregister call conditional on it
-        if ( stmt->clauses.at(i)->when_cond ) {
-            whenIndices.push_back(i);
-            ifCond = new LogicalExpr( cLoc,
-                new CastExpr( cLoc,
-                    new NameExpr( cLoc, clauseData.at(i)->whenName ), 
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                new CastExpr( cLoc,
-                    statusPtrCheck,
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                LogicalFlag::AndExpr
-            );
-        } else ifCond = statusPtrCheck;
-        
-        unregisters->push_back(
-            new IfStmt( cLoc,
-                ifCond,
-                new ExprStmt( cLoc, genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "unregister_select" ) ) 
-            )
-        );
-    }
-
-    if ( whenIndices.empty() || whenIndices.size() != stmt->clauses.size() ) {
-        body->push_back(
-                new ast::TryStmt( loc,
-                new CompoundStmt( loc, { recursiveOrIfGen( stmt, clauseData, 0, elseWhenName ) } ),
-                {},
-                new ast::FinallyClause( loc, unregisters )
-            )
-        );
-    } else { // If all clauses have whens, we need to skip the waituntil if they are all false
-        Expr * outerIfCond = new NameExpr( loc, clauseData.at( whenIndices.at(0) )->whenName );
-        Expr * lastExpr = outerIfCond;
-
-        for ( vector<int>::size_type i = 1; i < whenIndices.size(); i++ ) {
-            outerIfCond = new LogicalExpr( loc,
-                new CastExpr( loc,
-                    new NameExpr( loc, clauseData.at( whenIndices.at(i) )->whenName ), 
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                new CastExpr( loc,
-                    lastExpr,
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                LogicalFlag::OrExpr
-            );
-            lastExpr = outerIfCond;
-        }
-
-        body->push_back(
-                new ast::TryStmt( loc,
-                new CompoundStmt( loc, 
-                    {
-                        new IfStmt( loc,
-                            outerIfCond,
-                            recursiveOrIfGen( stmt, clauseData, 0, elseWhenName )
-                        )
-                    }
-                ),
-                {},
-                new ast::FinallyClause( loc, unregisters )
-            )
-        );
-    }
-
-    for ( ClauseData * datum : clauseData )
-        delete datum;
-
-    return body;
+	const CodeLocation & loc = stmt->location;
+	string statusName = namer_status.newName();
+	string elseWhenName = namer_when.newName();
+	int numClauses = stmt->clauses.size();
+	CompoundStmt * body = new CompoundStmt( stmt->location );
+
+	// Generates: unsigned long int status = 0;
+	body->push_back( new DeclStmt( loc,
+		new ObjectDecl( loc,
+			statusName,
+			new BasicType( BasicKind::LongUnsignedInt ),
+			new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
+		)
+	));
+
+	vector<ClauseData *> clauseData;
+	genClauseInits( stmt, clauseData, body, statusName, elseWhenName );
+
+	vector<int> whenIndices; // track which clauses have whens
+
+	CompoundStmt * unregisters = new CompoundStmt( loc );
+	Expr * ifCond;
+	for ( int i = 0; i < numClauses; i++ ) {
+		const CodeLocation & cLoc = stmt->clauses.at(i)->location;
+		// Gens: node.status != 0p
+		UntypedExpr * statusPtrCheck = new UntypedExpr( cLoc,
+			new NameExpr( cLoc, "?!=?" ),
+			{
+				ConstantExpr::null( cLoc, new PointerType( new BasicType( BasicKind::LongUnsignedInt ) ) ),
+				new UntypedExpr( cLoc,
+				    new NameExpr( cLoc, "__get_clause_status" ),
+				    { new NameExpr( cLoc, clauseData.at(i)->nodeName ) }
+				)
+			}
+		);
+
+		// If we have a when_cond make the unregister call conditional on it
+		if ( stmt->clauses.at(i)->when_cond ) {
+			whenIndices.push_back(i);
+			ifCond = new LogicalExpr( cLoc,
+				new CastExpr( cLoc,
+				    new NameExpr( cLoc, clauseData.at(i)->whenName ),
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				new CastExpr( cLoc,
+				    statusPtrCheck,
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				LogicalFlag::AndExpr
+			);
+		} else ifCond = statusPtrCheck;
+
+		unregisters->push_back(
+			new IfStmt( cLoc,
+				ifCond,
+				new ExprStmt( cLoc, genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "unregister_select" ) )
+			)
+		);
+	}
+
+	if ( whenIndices.empty() || whenIndices.size() != stmt->clauses.size() ) {
+		body->push_back(
+				new ast::TryStmt( loc,
+				new CompoundStmt( loc, { recursiveOrIfGen( stmt, clauseData, 0, elseWhenName ) } ),
+				{},
+				new ast::FinallyClause( loc, unregisters )
+			)
+		);
+	} else { // If all clauses have whens, we need to skip the waituntil if they are all false
+		Expr * outerIfCond = new NameExpr( loc, clauseData.at( whenIndices.at(0) )->whenName );
+		Expr * lastExpr = outerIfCond;
+
+		for ( vector<int>::size_type i = 1; i < whenIndices.size(); i++ ) {
+			outerIfCond = new LogicalExpr( loc,
+				new CastExpr( loc,
+				    new NameExpr( loc, clauseData.at( whenIndices.at(i) )->whenName ),
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				new CastExpr( loc,
+				    lastExpr,
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				LogicalFlag::OrExpr
+			);
+			lastExpr = outerIfCond;
+		}
+
+		body->push_back(
+				new ast::TryStmt( loc,
+				new CompoundStmt( loc,
+				    {
+				        new IfStmt( loc,
+				            outerIfCond,
+				            recursiveOrIfGen( stmt, clauseData, 0, elseWhenName )
+				        )
+				    }
+				),
+				{},
+				new ast::FinallyClause( loc, unregisters )
+			)
+		);
+	}
+
+	for ( ClauseData * datum : clauseData )
+		delete datum;
+
+	return body;
 }
 
 Stmt * GenerateWaitUntilCore::postvisit( const WaitUntilStmt * stmt ) {
-    if ( !selectNodeDecl )
-        SemanticError( stmt, "waituntil statement requires #include <waituntil.hfa>" );
-
-    // Prep clause tree to figure out how to set initial statuses
-    // setTreeSizes( stmt->predicateTree );
-    if ( paintWhenTree( stmt->predicateTree ) ) // if this returns true we can special case since tree is all OR's
-        return genAllOr( stmt );
-
-    CompoundStmt * tryBody = new CompoundStmt( stmt->location );
-    CompoundStmt * body = new CompoundStmt( stmt->location );
-    string statusArrName = namer_status.newName();
-    string pCountName = namer_park.newName();
-    string satName = namer_sat.newName();
-    string runName = namer_run.newName();
-    string elseWhenName = namer_when.newName();
-    int numClauses = stmt->clauses.size();
-    addPredicates( stmt, satName, runName );
-
-    const CodeLocation & loc = stmt->location;
-
-    // Generates: int park_counter = 0;
-    body->push_back( new DeclStmt( loc,
-        new ObjectDecl( loc,
-            pCountName,
-            new BasicType( BasicKind::SignedInt ),
-            new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
-        )
-    ));
-
-    // Generates: int clause_statuses[3] = { 0 };
-    body->push_back( new DeclStmt( loc,
-        new ObjectDecl( loc,
-            statusArrName,
-            new ArrayType( new BasicType( BasicKind::LongUnsignedInt ), ConstantExpr::from_int( loc, numClauses ), LengthFlag::FixedLen, DimensionFlag::DynamicDim ),
-            new ListInit( loc,
-                {
-                    new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
-                }
-            )
-        )
-    ));
-
-    vector<ClauseData *> clauseData;
-    genClauseInits( stmt, clauseData, body, statusArrName, elseWhenName );
-
-    vector<pair<int, WaitUntilStmt::ClauseNode *>> ambiguousClauses;       // list of ambiguous clauses
-    vector<int> andWhenClauses;    // list of clauses that have an AND op as a direct parent and when_cond defined
-
-    collectWhens( stmt->predicateTree, ambiguousClauses, andWhenClauses );
-
-    // This is only needed for clauses that have AND as a parent and a when_cond defined
-    // generates: if ( ! when_cond_0 ) clause_statuses_0 = __SELECT_RUN;
-    for ( int idx : andWhenClauses ) {
-        const CodeLocation & cLoc = stmt->clauses.at(idx)->location;
-        body->push_back( 
-            new IfStmt( cLoc,
-                new UntypedExpr ( cLoc,
-                    new NameExpr( cLoc, "!?" ),
-                    { new NameExpr( cLoc, clauseData.at(idx)->whenName ) }
-                ),  // IfStmt cond
-                new ExprStmt( cLoc,
-                    new UntypedExpr ( cLoc,
-                        new NameExpr( cLoc, "?=?" ),
-                        {
-                            new UntypedExpr ( cLoc, 
-                                new NameExpr( cLoc, "?[?]" ),
-                                {
-                                    new NameExpr( cLoc, statusArrName ),
-                                    ConstantExpr::from_int( cLoc, idx )
-                                }
-                            ),
-                            new NameExpr( cLoc, "__SELECT_RUN" )
-                        }
-                    )
-                )  // IfStmt then
-            )
-        );
-    }
-
-    // Only need to generate conditional initial state setting for ambiguous when clauses
-    if ( !ambiguousClauses.empty() ) {
-        body->push_back( genWhenStateConditions( stmt, clauseData, ambiguousClauses, 0 ) );
-    }
-
-    // generates the following for each clause:
-    // setup_clause( clause1, &clause_statuses[0], &park_counter );
-    // register_select(A, clause1);
-    for ( int i = 0; i < numClauses; i++ ) {
-        setUpClause( stmt->clauses.at(i), clauseData.at(i), pCountName, tryBody );
-    }
-
-    // generate satisfy logic based on if there is an else clause and if it is conditional
-    if ( stmt->else_stmt && stmt->else_cond ) { // gen both else/non else branches
-        tryBody->push_back(
-            new IfStmt( stmt->else_cond->location,
-                new NameExpr( stmt->else_cond->location, elseWhenName ),
-                genElseClauseBranch( stmt, runName, statusArrName, clauseData ),
-                genNoElseClauseBranch( stmt, runName, statusArrName, pCountName, clauseData )
-            )
-        );
-    } else if ( !stmt->else_stmt ) { // normal gen
-        tryBody->push_back( genNoElseClauseBranch( stmt, runName, statusArrName, pCountName, clauseData ) );
-    } else { // generate just else
-        tryBody->push_back( genElseClauseBranch( stmt, runName, statusArrName, clauseData ) );
-    }
-
-    // Collection of unregister calls on resources to be put in finally clause
-    // for each clause: 
-    // if ( !__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
-    // OR if when( ... ) defined on resource
-    // if ( when_cond_i && (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
-    CompoundStmt * unregisters = new CompoundStmt( loc );
-
-    Expr * statusExpr; // !__CFA_has_clause_run( clause_statuses[i] )
-    for ( int i = 0; i < numClauses; i++ ) {
-        const CodeLocation & cLoc = stmt->clauses.at(i)->location;
-
-        // Generates: !__CFA_has_clause_run( clause_statuses[i] )
-        statusExpr = new UntypedExpr ( cLoc,
-            new NameExpr( cLoc, "!?" ),
-            {
-                new UntypedExpr ( cLoc, 
-                    new NameExpr( cLoc, "__CFA_has_clause_run" ),
-                    {
-                        genArrAccessExpr( cLoc, i, statusArrName )
-                    }
-                )
-            }
-        );
-        
-        // Generates:
-        // (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
-        statusExpr = new LogicalExpr( cLoc,
-            new CastExpr( cLoc,
-                statusExpr, 
-                new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-            ),
-            new CastExpr( cLoc,
-                genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "unregister_select" ),
-                new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-            ),
-            LogicalFlag::AndExpr
-        );
-        
-        // if when cond defined generates:
-        // when_cond_i && (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
-        if ( stmt->clauses.at(i)->when_cond )
-            statusExpr = new LogicalExpr( cLoc,
-                new CastExpr( cLoc,
-                    new NameExpr( cLoc, clauseData.at(i)->whenName ), 
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                new CastExpr( cLoc,
-                    statusExpr,
-                    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast 
-                ),
-                LogicalFlag::AndExpr
-            );
-
-        // generates:
-        // if ( statusExpr ) { ... clausei stmt ... }
-        unregisters->push_back( 
-            new IfStmt( cLoc,
-                statusExpr,
-                new CompoundStmt( cLoc,
-                    {
-                        new IfStmt( cLoc,
-                            genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "on_selected" ),
-                            ast::deepCopy( stmt->clauses.at(i)->stmt )
-                        )
-                    }
-                )
-            )
-        );
-
-        // // generates:
-        // // if ( statusExpr ) { ... clausei stmt ... }
-        // unregisters->push_back( 
-        //     new IfStmt( cLoc,
-        //         statusExpr,
-        //         genStmtBlock( stmt->clauses.at(i), clauseData.at(i) )
-        //     )
-        // );
-    }
-
-    body->push_back( 
-        new ast::TryStmt(
-            loc,
-            tryBody,
-            {},
-            new ast::FinallyClause( loc, unregisters )
-        )
-    );
-
-    for ( ClauseData * datum : clauseData )
-        delete datum;
-
-    return body;
+	if ( !selectNodeDecl )
+		SemanticError( stmt, "waituntil statement requires #include <waituntil.hfa>" );
+
+	// Prep clause tree to figure out how to set initial statuses
+	// setTreeSizes( stmt->predicateTree );
+	if ( paintWhenTree( stmt->predicateTree ) ) // if this returns true we can special case since tree is all OR's
+		return genAllOr( stmt );
+
+	CompoundStmt * tryBody = new CompoundStmt( stmt->location );
+	CompoundStmt * body = new CompoundStmt( stmt->location );
+	string statusArrName = namer_status.newName();
+	string pCountName = namer_park.newName();
+	string satName = namer_sat.newName();
+	string runName = namer_run.newName();
+	string elseWhenName = namer_when.newName();
+	int numClauses = stmt->clauses.size();
+	addPredicates( stmt, satName, runName );
+
+	const CodeLocation & loc = stmt->location;
+
+	// Generates: int park_counter = 0;
+	body->push_back( new DeclStmt( loc,
+		new ObjectDecl( loc,
+			pCountName,
+			new BasicType( BasicKind::SignedInt ),
+			new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
+		)
+	));
+
+	// Generates: int clause_statuses[3] = { 0 };
+	body->push_back( new DeclStmt( loc,
+		new ObjectDecl( loc,
+			statusArrName,
+			new ArrayType( new BasicType( BasicKind::LongUnsignedInt ), ConstantExpr::from_int( loc, numClauses ), LengthFlag::FixedLen, DimensionFlag::DynamicDim ),
+			new ListInit( loc,
+				{
+				    new SingleInit( loc, ConstantExpr::from_int( loc, 0 ) )
+				}
+			)
+		)
+	));
+
+	vector<ClauseData *> clauseData;
+	genClauseInits( stmt, clauseData, body, statusArrName, elseWhenName );
+
+	vector<pair<int, WaitUntilStmt::ClauseNode *>> ambiguousClauses;       // list of ambiguous clauses
+	vector<int> andWhenClauses;    // list of clauses that have an AND op as a direct parent and when_cond defined
+
+	collectWhens( stmt->predicateTree, ambiguousClauses, andWhenClauses );
+
+	// This is only needed for clauses that have AND as a parent and a when_cond defined
+	// generates: if ( ! when_cond_0 ) clause_statuses_0 = __SELECT_RUN;
+	for ( int idx : andWhenClauses ) {
+		const CodeLocation & cLoc = stmt->clauses.at(idx)->location;
+		body->push_back(
+			new IfStmt( cLoc,
+				new UntypedExpr ( cLoc,
+				    new NameExpr( cLoc, "!?" ),
+				    { new NameExpr( cLoc, clauseData.at(idx)->whenName ) }
+				),  // IfStmt cond
+				new ExprStmt( cLoc,
+				    new UntypedExpr ( cLoc,
+				        new NameExpr( cLoc, "?=?" ),
+				        {
+				            new UntypedExpr ( cLoc,
+				                new NameExpr( cLoc, "?[?]" ),
+				                {
+				                    new NameExpr( cLoc, statusArrName ),
+				                    ConstantExpr::from_int( cLoc, idx )
+				                }
+				            ),
+				            new NameExpr( cLoc, "__SELECT_RUN" )
+				        }
+				    )
+				)  // IfStmt then
+			)
+		);
+	}
+
+	// Only need to generate conditional initial state setting for ambiguous when clauses
+	if ( !ambiguousClauses.empty() ) {
+		body->push_back( genWhenStateConditions( stmt, clauseData, ambiguousClauses, 0 ) );
+	}
+
+	// generates the following for each clause:
+	// setup_clause( clause1, &clause_statuses[0], &park_counter );
+	// register_select(A, clause1);
+	for ( int i = 0; i < numClauses; i++ ) {
+		setUpClause( stmt->clauses.at(i), clauseData.at(i), pCountName, tryBody );
+	}
+
+	// generate satisfy logic based on if there is an else clause and if it is conditional
+	if ( stmt->else_stmt && stmt->else_cond ) { // gen both else/non else branches
+		tryBody->push_back(
+			new IfStmt( stmt->else_cond->location,
+				new NameExpr( stmt->else_cond->location, elseWhenName ),
+				genElseClauseBranch( stmt, runName, statusArrName, clauseData ),
+				genNoElseClauseBranch( stmt, runName, statusArrName, pCountName, clauseData )
+			)
+		);
+	} else if ( !stmt->else_stmt ) { // normal gen
+		tryBody->push_back( genNoElseClauseBranch( stmt, runName, statusArrName, pCountName, clauseData ) );
+	} else { // generate just else
+		tryBody->push_back( genElseClauseBranch( stmt, runName, statusArrName, clauseData ) );
+	}
+
+	// Collection of unregister calls on resources to be put in finally clause
+	// for each clause:
+	// if ( !__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
+	// OR if when( ... ) defined on resource
+	// if ( when_cond_i && (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei ) ) { ... clausei stmt ... }
+	CompoundStmt * unregisters = new CompoundStmt( loc );
+
+	Expr * statusExpr; // !__CFA_has_clause_run( clause_statuses[i] )
+	for ( int i = 0; i < numClauses; i++ ) {
+		const CodeLocation & cLoc = stmt->clauses.at(i)->location;
+
+		// Generates: !__CFA_has_clause_run( clause_statuses[i] )
+		statusExpr = new UntypedExpr ( cLoc,
+			new NameExpr( cLoc, "!?" ),
+			{
+				new UntypedExpr ( cLoc,
+				    new NameExpr( cLoc, "__CFA_has_clause_run" ),
+				    {
+				        genArrAccessExpr( cLoc, i, statusArrName )
+				    }
+				)
+			}
+		);
+
+		// Generates:
+		// (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
+		statusExpr = new LogicalExpr( cLoc,
+			new CastExpr( cLoc,
+				statusExpr,
+				new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+			),
+			new CastExpr( cLoc,
+				genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "unregister_select" ),
+				new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+			),
+			LogicalFlag::AndExpr
+		);
+
+		// if when cond defined generates:
+		// when_cond_i && (!__CFA_has_clause_run( clause_statuses[i] )) && unregister_select( ... , clausei );
+		if ( stmt->clauses.at(i)->when_cond )
+			statusExpr = new LogicalExpr( cLoc,
+				new CastExpr( cLoc,
+				    new NameExpr( cLoc, clauseData.at(i)->whenName ),
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				new CastExpr( cLoc,
+				    statusExpr,
+				    new BasicType( BasicKind::Bool ), GeneratedFlag::ExplicitCast
+				),
+				LogicalFlag::AndExpr
+			);
+
+		// generates:
+		// if ( statusExpr ) { ... clausei stmt ... }
+		unregisters->push_back(
+			new IfStmt( cLoc,
+				statusExpr,
+				new CompoundStmt( cLoc,
+				    {
+				        new IfStmt( cLoc,
+				            genSelectTraitCall( stmt->clauses.at(i), clauseData.at(i), "on_selected" ),
+				            ast::deepCopy( stmt->clauses.at(i)->stmt )
+				        )
+				    }
+				)
+			)
+		);
+
+		// // generates:
+		// // if ( statusExpr ) { ... clausei stmt ... }
+		// unregisters->push_back(
+		//     new IfStmt( cLoc,
+		//         statusExpr,
+		//         genStmtBlock( stmt->clauses.at(i), clauseData.at(i) )
+		//     )
+		// );
+	}
+
+	body->push_back(
+		new ast::TryStmt(
+			loc,
+			tryBody,
+			{},
+			new ast::FinallyClause( loc, unregisters )
+		)
+	);
+
+	for ( ClauseData * datum : clauseData )
+		delete datum;
+
+	return body;
 }
 
@@ -1399,25 +1399,25 @@
 // Predicates are added after "struct select_node { ... };"
 class AddPredicateDecls final : public WithDeclsToAdd<> {
-    vector<FunctionDecl *> & satFns;
-    const StructDecl * selectNodeDecl = nullptr;
+	vector<FunctionDecl *> & satFns;
+	const StructDecl * selectNodeDecl = nullptr;
 
   public:
-    void previsit( const StructDecl * decl ) {
-        if ( !decl->body ) {
-            return;
-        } else if ( "select_node" == decl->name ) {
-            assert( !selectNodeDecl );
-            selectNodeDecl = decl;
-            for ( FunctionDecl * fn : satFns )
-                declsToAddAfter.push_back(fn);            
-        }
-    }
-    AddPredicateDecls( vector<FunctionDecl *> & satFns ): satFns(satFns) {}
+	void previsit( const StructDecl * decl ) {
+		if ( !decl->body ) {
+			return;
+		} else if ( "select_node" == decl->name ) {
+			assert( !selectNodeDecl );
+			selectNodeDecl = decl;
+			for ( FunctionDecl * fn : satFns )
+				declsToAddAfter.push_back(fn);
+		}
+	}
+	AddPredicateDecls( vector<FunctionDecl *> & satFns ): satFns(satFns) {}
 };
 
 void generateWaitUntil( TranslationUnit & translationUnit ) {
-    vector<FunctionDecl *> satFns;
+	vector<FunctionDecl *> satFns;
 	Pass<GenerateWaitUntilCore>::run( translationUnit, satFns );
-    Pass<AddPredicateDecls>::run( translationUnit, satFns );
+	Pass<AddPredicateDecls>::run( translationUnit, satFns );
 }
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -1412,10 +1412,10 @@
 	}
 
-    void Finder::postvisit(const ast::VariableExpr *variableExpr) {
-        // not sufficient to just pass `variableExpr` here, type might have changed
-
-        auto cand = new Candidate(variableExpr, tenv);
-        candidates.emplace_back(cand);
-    }
+	void Finder::postvisit(const ast::VariableExpr *variableExpr) {
+		// not sufficient to just pass `variableExpr` here, type might have changed
+
+		auto cand = new Candidate(variableExpr, tenv);
+		candidates.emplace_back(cand);
+	}
 
 	void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
@@ -2133,6 +2133,6 @@
 
 // get the valueE(...) ApplicationExpr that returns the enum value
-const ast::Expr * getValueEnumCall( 
-	const ast::Expr * expr, 
+const ast::Expr * getValueEnumCall(
+	const ast::Expr * expr,
 	const ResolvExpr::ResolveContext & context, const ast::TypeEnvironment & env ) {
 		auto callExpr = new ast::UntypedExpr(
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/ResolvExpr/CommonType.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -397,15 +397,15 @@
 			}
 		} else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) {
-            if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) {
-			    ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
-			    if (
-				    ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
-					    || widen.first )
-				    && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
-					    || widen.second )
-			    ) {
-				    result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
-			    }
-            }
+			if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) {
+				ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
+				if (
+					( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
+						|| widen.first )
+					&& ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
+						|| widen.second )
+				) {
+					result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
+				}
+			}
 		}
 	}
@@ -519,5 +519,5 @@
 								// xxx - assume LHS is always the target type
 
-								if ( ! ((widen.second && ref2->qualifiers.is_mutex) 
+								if ( ! ((widen.second && ref2->qualifiers.is_mutex)
 								|| (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return;
 
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/ResolvExpr/ConversionCost.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -379,28 +379,28 @@
 
 void ConversionCost::postvisit( const ast::EnumAttrType * src ) {
-    auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
+	auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
 	assert( src->attr != ast::EnumAttribute::Label );
-    if ( src->attr == ast::EnumAttribute::Value ) {
-        if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
-            cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
-        } else {
-            auto baseType = src->instance->base->base;
-            cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
+	if ( src->attr == ast::EnumAttribute::Value ) {
+		if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
+			cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
+		} else {
+			auto baseType = src->instance->base->base;
+			cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
 			if ( cost < Cost::infinity ) {
 				cost.incUnsafe();
 			}
-        }
-    } else { // ast::EnumAttribute::Posn
-        if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
-		    cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
-		    if ( cost < Cost::unsafe ) cost.incSafe();
-	    } else {
-		    static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
-		    cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
-		    if ( cost < Cost::unsafe ) {
-			    cost.incSafe();
-		    }
-	    }
-    }
+		}
+	} else { // ast::EnumAttribute::Posn
+		if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
+			cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
+			if ( cost < Cost::unsafe ) cost.incSafe();
+		} else {
+			static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
+			cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
+			if ( cost < Cost::unsafe ) {
+				cost.incSafe();
+			}
+		}
+	}
 }
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/ResolvExpr/Unify.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -307,5 +307,5 @@
 				// type unification calls expression unification (mutual recursion)
 				if ( ! unify(array->dimension, array2->dimension,
-				    tenv, need, have, open, widen) ) return;
+					tenv, need, have, open, widen) ) return;
 			}
 
@@ -455,5 +455,5 @@
 			// check that the other type is compatible and named the same
 			auto otherInst = dynamic_cast< const XInstType * >( other );
-			if (otherInst && inst->name == otherInst->name) 
+			if (otherInst && inst->name == otherInst->name)
 				this->result = otherInst;
 			return otherInst;
@@ -542,8 +542,8 @@
 			// Lazy approach for now
 			if ( auto otherPos = dynamic_cast< const ast::EnumAttrType *>(type2) ) {
-			    if ( enumAttr->match(otherPos) ) {
-				    result = otherPos;
-			    }
-            }  
+				if ( enumAttr->match(otherPos) ) {
+					result = otherPos;
+				}
+			}
 		}
 
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/SymTab/Mangler.cc	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -283,16 +283,16 @@
 	postvisit( enumAttr->instance );
 	// mangleName += "_pos";
-    switch ( enumAttr->attr )
-    {
-        case ast::EnumAttribute::Label:
-            mangleName += "_label_";
-            break;
-        case ast::EnumAttribute::Posn:
+	switch ( enumAttr->attr )
+	{
+		case ast::EnumAttribute::Label:
+			mangleName += "_label_";
+			break;
+		case ast::EnumAttribute::Posn:
 			mangleName += "_posn_";
-            break;
-        case ast::EnumAttribute::Value:
-            mangleName += "_value_";
-            break;
-    }
+			break;
+		case ast::EnumAttribute::Value:
+			mangleName += "_value_";
+			break;
+	}
 
 }
Index: src/Validate/ForallPointerDecay.hpp
===================================================================
--- src/Validate/ForallPointerDecay.hpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Validate/ForallPointerDecay.hpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -39,5 +39,5 @@
 /// Expand all traits in an assertion list.
 std::vector<ast::ptr<ast::DeclWithType>> expandAssertions(
-        std::vector<ast::ptr<ast::DeclWithType>> const & );
+		std::vector<ast::ptr<ast::DeclWithType>> const & );
 
 }
Index: src/Validate/HoistStruct.cpp
===================================================================
--- src/Validate/HoistStruct.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Validate/HoistStruct.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -149,20 +149,20 @@
 template<typename InstType>
 InstType const * HoistStructCore::preCollectionInstType( InstType const * type ) {
-    if ( !type->base->parent ) return type;
-    if ( type->base->params.empty() ) return type;
-
-    InstType * mut = ast::mutate( type );
-    ast::AggregateDecl const * parent =
-        commonParent( this->parent, mut->base->parent );
-    assert( parent );
-
-    std::vector<ast::ptr<ast::Expr>> args;
-    for ( const ast::ptr<ast::TypeDecl> & param : parent->params ) {
-        args.emplace_back( new ast::TypeExpr( param->location,
-            new ast::TypeInstType( param )
-        ) );
-    }
-    spliceBegin( mut->params, args );
-    return mut;
+	if ( !type->base->parent ) return type;
+	if ( type->base->params.empty() ) return type;
+
+	InstType * mut = ast::mutate( type );
+	ast::AggregateDecl const * parent =
+		commonParent( this->parent, mut->base->parent );
+	assert( parent );
+
+	std::vector<ast::ptr<ast::Expr>> args;
+	for ( const ast::ptr<ast::TypeDecl> & param : parent->params ) {
+		args.emplace_back( new ast::TypeExpr( param->location,
+			new ast::TypeInstType( param )
+		) );
+	}
+	spliceBegin( mut->params, args );
+	return mut;
 }
 
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Validate/ImplementEnumFunc.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -8,523 +8,522 @@
 namespace {
 class EnumAttrFuncGenerator {
-    const ast::EnumDecl* decl;
-    const ast::EnumInstType* instType;
-    // const ast::EnumAttrType* attrType;
-    unsigned int functionNesting;
-    ast::Linkage::Spec proto_linkage;
-
-   public:
-    std::list<ast::ptr<ast::Decl>> forwards;
-    std::list<ast::ptr<ast::Decl>> definitions;
-
-    void generateAndAppendFunctions(std::list<ast::ptr<ast::Decl>>&);
-
-    EnumAttrFuncGenerator(const ast::EnumDecl* decl,
-                          const ast::EnumInstType* instType,
-                          // const ast::EnumAttrType* enumAttrType,
-                          unsigned int functionNesting)
-        : decl(decl),
-          instType{instType},
-          // attrType{enumAttrType},
-          functionNesting{functionNesting},
-          proto_linkage{ast::Linkage::Cforall} {}
-
-    void genAttrFunctions();
-    void genSuccPredPosn();
-    void genSuccPredDecl();
-
-    void appendReturnThis(ast::FunctionDecl* decl) {
-        assert(1 <= decl->params.size());
-        assert(1 == decl->returns.size());
-        assert(decl->stmts);
-
-        const CodeLocation& location = (decl->stmts->kids.empty())
-                                           ? decl->stmts->location
-                                           : decl->stmts->kids.back()->location;
-        const ast::DeclWithType* thisParam = decl->params.front();
-        decl->stmts.get_and_mutate()->push_back(new ast::ReturnStmt(
-            location, new ast::VariableExpr(location, thisParam)));
-    }
-    void genAttrStandardFuncs() {
-        ast::FunctionDecl* (EnumAttrFuncGenerator::*standardProtos[4])()
-            const = {&EnumAttrFuncGenerator::genCtorProto,
-                     &EnumAttrFuncGenerator::genCopyProto,
-                     &EnumAttrFuncGenerator::genDtorProto,
-                     &EnumAttrFuncGenerator::genAssignProto};
-        for (auto& generator : standardProtos) {
-            ast::FunctionDecl* decl = (this->*generator)();
-            produceForwardDecl(decl);
-            genFuncBody(decl);
-            if (CodeGen::isAssignment(decl->name)) {
-                appendReturnThis(decl);
-            }
-            produceDecl(decl);
-        }
-    }
-
-   private:
-    const CodeLocation& getLocation() const { return decl->location; }
-
-    ast::FunctionDecl* genProto(
-        std::string&& name, std::vector<ast::ptr<ast::DeclWithType>>&& params,
-        std::vector<ast::ptr<ast::DeclWithType>>&& returns) const;
-
-    void produceDecl(const ast::FunctionDecl* decl);
-    void produceForwardDecl(const ast::FunctionDecl* decl);
-
-    const ast::Decl* getDecl() const { return decl; }
-
-    ast::FunctionDecl* genPosnProto() const;
-    ast::FunctionDecl* genLabelProto() const;
-    ast::FunctionDecl* genValueProto() const;
-    ast::FunctionDecl* genSuccProto() const;
-    ast::FunctionDecl* genPredProto() const;
-
-    ast::FunctionDecl* genSuccPosProto() const;
-    ast::FunctionDecl* genPredPosProto() const;
-
-    // ---------------------------------------------------
-    // ast::FunctionDecl* genAttrCtorProto() const;
-    /// Changes the node inside a pointer so that it has the unused attribute.
-    void addUnusedAttribute(ast::ptr<ast::DeclWithType>& declPtr) {
-        ast::DeclWithType* decl = declPtr.get_and_mutate();
-        decl->attributes.push_back(new ast::Attribute("unused"));
-    }
-
-    ast::ObjectDecl* dstParam() const {
-        return new ast::ObjectDecl(getLocation(), "_dst",
-                                   new ast::ReferenceType(new ast::EnumAttrType(
-                                       ast::deepCopy(instType))));
-    }
-
-    ast::ObjectDecl* srcParam() const {
-        return new ast::ObjectDecl(
-            getLocation(), "_src",
-            new ast::EnumAttrType(ast::deepCopy(instType)));
-    }
-
-    /// E = EnumAttrType<T>`
-    /// `void ?{}(E & _dst)`.
-    ast::FunctionDecl* genCtorProto() const {
-        return genProto("?{}", {dstParam()}, {});
-    }
-
-    /// void ?{}(E & _dst, E _src)`.
-    ast::FunctionDecl* genCopyProto() const {
-        return genProto("?{}", {dstParam(), srcParam()}, {});
-    }
-
-    ///`void ^?{}(E & _dst)`.
-    ast::FunctionDecl* genDtorProto() const {
-        // The destructor must be mutex on a concurrent type.
-        return genProto("^?{}", {dstParam()}, {});
-    }
-
-    /// `E ?{}(E & _dst, E _src)`.
-    ast::FunctionDecl* genAssignProto() const {
-        // Only the name is different, so just reuse the generation function.
-        auto retval = srcParam();
-        retval->name = "_ret";
-        return genProto("?=?", {dstParam(), srcParam()}, {retval});
-    }
-
-    void genFuncBody(ast::FunctionDecl* func) {
-        const CodeLocation& location = func->location;
-        auto& params = func->params;
-        if (InitTweak::isCopyConstructor(func) ||
-            InitTweak::isAssignment(func)) {
-            assert(2 == params.size());
-            auto dstParam = params.front().strict_as<ast::ObjectDecl>();
-            auto srcParam = params.back().strict_as<ast::ObjectDecl>();
-            func->stmts = genCopyBody(location, dstParam, srcParam);
-        } else {
-            assert(1 == params.size());
-            // Default constructor and destructor is empty.
-            func->stmts = new ast::CompoundStmt(location);
-            // Add unused attribute to parameter to silence warnings.
-            addUnusedAttribute(params.front());
-
-            // Just an extra step to make the forward and declaration match.
-            if (forwards.empty()) return;
-            ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>(
-                forwards.back().get_and_mutate());
-            addUnusedAttribute(fwd->params.front());
-        }
-    }
-
-    const ast::CompoundStmt* genCopyBody(const CodeLocation& location,
-                                         const ast::ObjectDecl* dstParam,
-                                         const ast::ObjectDecl* srcParam) {
-        return new ast::CompoundStmt(
-            location,
-            {new ast::ExprStmt(
-                location,
-                new ast::UntypedExpr(
-                    location, new ast::NameExpr(location, "__builtin_memcpy"),
-                    {
-                        new ast::AddressExpr(location, new ast::VariableExpr(
-                                                           location, dstParam)),
-                        new ast::AddressExpr(location, new ast::VariableExpr(
-                                                           location, srcParam)),
-                        new ast::SizeofExpr(location, srcParam->type),
-                    }))});
-    }
-
-    void genDtorBody(ast::FunctionDecl* func) {
-        const CodeLocation& location = func->location;
-        auto& params = func->params;
-        assert(1 == params.size());
-        func->stmts = new ast::CompoundStmt(location);
-        addUnusedAttribute(params.front());
-
-        // Just an extra step to make the forward and declaration match.
-        if (forwards.empty()) return;
-        ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>(
-            forwards.back().get_and_mutate());
-        addUnusedAttribute(fwd->params.front());
-    }
-
-    // ast::FunctionDecl*
-    // ----------------------------------------------------
-
-    ast::FunctionDecl* genSuccPredFunc(bool succ);
-
-    const ast::Init* getAutoInit(const ast::Init* prev) const;
-
-    std::vector<ast::ptr<ast::Init>> genLabelInit() const;
-
-    std::vector<ast::ptr<ast::Init>> genValueInit() const;
-    ast::ObjectDecl* genAttrArrayProto(
-        const ast::EnumAttribute attr, const CodeLocation& location,
-        std::vector<ast::ptr<ast::Init>>& inits) const;
-    void genValueOrLabelBody(ast::FunctionDecl* func,
-                             ast::ObjectDecl* arrDecl) const;
-    void genPosnBody(ast::FunctionDecl* func) const;
-    void genAttributesDecls(const ast::EnumAttribute attr);
+	const ast::EnumDecl* decl;
+	const ast::EnumInstType* instType;
+	unsigned int functionNesting;
+	ast::Linkage::Spec proto_linkage;
+
+public:
+	std::list<ast::ptr<ast::Decl>> forwards;
+	std::list<ast::ptr<ast::Decl>> definitions;
+
+	void generateAndAppendFunctions(std::list<ast::ptr<ast::Decl>>&);
+
+	EnumAttrFuncGenerator(
+			const ast::EnumDecl* decl,
+			const ast::EnumInstType* instType,
+			unsigned int functionNesting )
+		: decl(decl),
+		  instType{instType},
+		  functionNesting{functionNesting},
+		  proto_linkage{ast::Linkage::Cforall} {}
+
+	void genAttrFunctions();
+	void genSuccPredPosn();
+	void genSuccPredDecl();
+
+	void appendReturnThis(ast::FunctionDecl* decl) {
+		assert(1 <= decl->params.size());
+		assert(1 == decl->returns.size());
+		assert(decl->stmts);
+
+		const CodeLocation& location = (decl->stmts->kids.empty())
+		                                   ? decl->stmts->location
+		                                   : decl->stmts->kids.back()->location;
+		const ast::DeclWithType* thisParam = decl->params.front();
+		decl->stmts.get_and_mutate()->push_back(new ast::ReturnStmt(
+			location, new ast::VariableExpr(location, thisParam)));
+	}
+	void genAttrStandardFuncs() {
+		ast::FunctionDecl* (EnumAttrFuncGenerator::*standardProtos[4])()
+			const = {&EnumAttrFuncGenerator::genCtorProto,
+					 &EnumAttrFuncGenerator::genCopyProto,
+					 &EnumAttrFuncGenerator::genDtorProto,
+					 &EnumAttrFuncGenerator::genAssignProto};
+		for (auto& generator : standardProtos) {
+			ast::FunctionDecl* decl = (this->*generator)();
+			produceForwardDecl(decl);
+			genFuncBody(decl);
+			if (CodeGen::isAssignment(decl->name)) {
+				appendReturnThis(decl);
+			}
+			produceDecl(decl);
+		}
+	}
+
+private:
+	const CodeLocation& getLocation() const { return decl->location; }
+
+	ast::FunctionDecl* genProto(
+		std::string&& name, std::vector<ast::ptr<ast::DeclWithType>>&& params,
+		std::vector<ast::ptr<ast::DeclWithType>>&& returns) const;
+
+	void produceDecl(const ast::FunctionDecl* decl);
+	void produceForwardDecl(const ast::FunctionDecl* decl);
+
+	const ast::Decl* getDecl() const { return decl; }
+
+	ast::FunctionDecl* genPosnProto() const;
+	ast::FunctionDecl* genLabelProto() const;
+	ast::FunctionDecl* genValueProto() const;
+	ast::FunctionDecl* genSuccProto() const;
+	ast::FunctionDecl* genPredProto() const;
+
+	ast::FunctionDecl* genSuccPosProto() const;
+	ast::FunctionDecl* genPredPosProto() const;
+
+	// ---------------------------------------------------
+	// ast::FunctionDecl* genAttrCtorProto() const;
+	/// Changes the node inside a pointer so that it has the unused attribute.
+	void addUnusedAttribute(ast::ptr<ast::DeclWithType>& declPtr) {
+		ast::DeclWithType* decl = declPtr.get_and_mutate();
+		decl->attributes.push_back(new ast::Attribute("unused"));
+	}
+
+	ast::ObjectDecl* dstParam() const {
+		return new ast::ObjectDecl(getLocation(), "_dst",
+		                           new ast::ReferenceType(new ast::EnumAttrType(
+		                               ast::deepCopy(instType))));
+	}
+
+	ast::ObjectDecl* srcParam() const {
+		return new ast::ObjectDecl(
+			getLocation(), "_src",
+			new ast::EnumAttrType(ast::deepCopy(instType)));
+	}
+
+	/// E = EnumAttrType<T>`
+	/// `void ?{}(E & _dst)`.
+	ast::FunctionDecl* genCtorProto() const {
+		return genProto("?{}", {dstParam()}, {});
+	}
+
+	/// void ?{}(E & _dst, E _src)`.
+	ast::FunctionDecl* genCopyProto() const {
+		return genProto("?{}", {dstParam(), srcParam()}, {});
+	}
+
+	///`void ^?{}(E & _dst)`.
+	ast::FunctionDecl* genDtorProto() const {
+		// The destructor must be mutex on a concurrent type.
+		return genProto("^?{}", {dstParam()}, {});
+	}
+
+	/// `E ?{}(E & _dst, E _src)`.
+	ast::FunctionDecl* genAssignProto() const {
+		// Only the name is different, so just reuse the generation function.
+		auto retval = srcParam();
+		retval->name = "_ret";
+		return genProto("?=?", {dstParam(), srcParam()}, {retval});
+	}
+
+	void genFuncBody(ast::FunctionDecl* func) {
+		const CodeLocation& location = func->location;
+		auto& params = func->params;
+		if (InitTweak::isCopyConstructor(func) ||
+			InitTweak::isAssignment(func)) {
+			assert(2 == params.size());
+			auto dstParam = params.front().strict_as<ast::ObjectDecl>();
+			auto srcParam = params.back().strict_as<ast::ObjectDecl>();
+			func->stmts = genCopyBody(location, dstParam, srcParam);
+		} else {
+			assert(1 == params.size());
+			// Default constructor and destructor is empty.
+			func->stmts = new ast::CompoundStmt(location);
+			// Add unused attribute to parameter to silence warnings.
+			addUnusedAttribute(params.front());
+
+			// Just an extra step to make the forward and declaration match.
+			if (forwards.empty()) return;
+			ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>(
+				forwards.back().get_and_mutate());
+			addUnusedAttribute(fwd->params.front());
+		}
+	}
+
+	const ast::CompoundStmt* genCopyBody( const CodeLocation& location,
+			const ast::ObjectDecl* dstParam, const ast::ObjectDecl* srcParam) {
+		return new ast::CompoundStmt(
+			location,
+			{new ast::ExprStmt(
+				location,
+				new ast::UntypedExpr(
+					location, new ast::NameExpr(location, "__builtin_memcpy"),
+					{
+						new ast::AddressExpr( location,
+							new ast::VariableExpr( location, dstParam ) ),
+						new ast::AddressExpr( location,
+							new ast::VariableExpr( location, srcParam ) ),
+						new ast::SizeofExpr( location, srcParam->type ),
+					}))});
+	}
+
+	void genDtorBody(ast::FunctionDecl* func) {
+		const CodeLocation& location = func->location;
+		auto& params = func->params;
+		assert(1 == params.size());
+		func->stmts = new ast::CompoundStmt(location);
+		addUnusedAttribute(params.front());
+
+		// Just an extra step to make the forward and declaration match.
+		if (forwards.empty()) return;
+		ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>(
+			forwards.back().get_and_mutate());
+		addUnusedAttribute(fwd->params.front());
+	}
+
+	// ast::FunctionDecl*
+	// ----------------------------------------------------
+
+	ast::FunctionDecl* genSuccPredFunc(bool succ);
+
+	const ast::Init* getAutoInit(const ast::Init* prev) const;
+
+	std::vector<ast::ptr<ast::Init>> genLabelInit() const;
+
+	std::vector<ast::ptr<ast::Init>> genValueInit() const;
+	ast::ObjectDecl* genAttrArrayProto(
+		const ast::EnumAttribute attr, const CodeLocation& location,
+		std::vector<ast::ptr<ast::Init>>& inits) const;
+	void genValueOrLabelBody(
+		ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const;
+	void genPosnBody(ast::FunctionDecl* func) const;
+	void genAttributesDecls(const ast::EnumAttribute attr);
 };
 
 std::vector<ast::ptr<ast::Init>> EnumAttrFuncGenerator::genLabelInit() const {
-    std::vector<ast::ptr<ast::Init>> inits;
-    for (size_t i = 0; i < decl->members.size(); i++) {
-        ast::ptr<ast::Decl> mem = decl->members.at(i);
-        auto memAsObjectDecl = mem.as<ast::ObjectDecl>();
-        assert(memAsObjectDecl);
-        inits.emplace_back(new ast::SingleInit(
-            mem->location,
-            ast::ConstantExpr::from_string(mem->location, mem->name)));
-    }
-    return inits;
+	std::vector<ast::ptr<ast::Init>> inits;
+	for (size_t i = 0; i < decl->members.size(); i++) {
+		ast::ptr<ast::Decl> mem = decl->members.at(i);
+		auto memAsObjectDecl = mem.as<ast::ObjectDecl>();
+		assert(memAsObjectDecl);
+		inits.emplace_back(new ast::SingleInit(
+			mem->location,
+			ast::ConstantExpr::from_string(mem->location, mem->name)));
+	}
+	return inits;
 }
 
 std::vector<ast::ptr<ast::Init>> EnumAttrFuncGenerator::genValueInit() const {
-    std::vector<ast::ptr<ast::Init>> inits;
-    for (size_t i = 0; i < decl->members.size(); i++) {
-        ast::ptr<ast::Decl> mem = decl->members.at(i);
-        auto memAsObjectDecl = mem.as<ast::ObjectDecl>();
-        assert(memAsObjectDecl);
-        if (memAsObjectDecl->init) {
-            inits.emplace_back(memAsObjectDecl->init);
-        } else {
-            const CodeLocation& location = mem->location;
-            if (i == 0) {
-                inits.emplace_back(new ast::SingleInit(
-                    location, ast::ConstantExpr::from_int(mem->location, 0)));
-            } else {
-                inits.emplace_back(getAutoInit(inits.at(i - 1)));
-            }
-        }
-    }
-    return inits;
+	std::vector<ast::ptr<ast::Init>> inits;
+	for (size_t i = 0; i < decl->members.size(); i++) {
+		ast::ptr<ast::Decl> mem = decl->members.at(i);
+		auto memAsObjectDecl = mem.as<ast::ObjectDecl>();
+		assert(memAsObjectDecl);
+		if (memAsObjectDecl->init) {
+			inits.emplace_back(memAsObjectDecl->init);
+		} else {
+			const CodeLocation& location = mem->location;
+			if (i == 0) {
+				inits.emplace_back(new ast::SingleInit(
+					location, ast::ConstantExpr::from_int(mem->location, 0)));
+			} else {
+				inits.emplace_back(getAutoInit(inits.at(i - 1)));
+			}
+		}
+	}
+	return inits;
 }
 const ast::Init* EnumAttrFuncGenerator::getAutoInit(
-    const ast::Init* prev) const {
-    if (prev == nullptr) {
-        return new ast::SingleInit(
-            getLocation(), ast::ConstantExpr::from_int(getLocation(), 0));
-    }
-    auto prevInit = dynamic_cast<const ast::SingleInit*>(prev);
-    assert(prevInit);
-    auto prevInitExpr = prevInit->value;
-    if (auto constInit = prevInitExpr.as<ast::ConstantExpr>()) {
-        // Assume no string literal for now
-        return new ast::SingleInit(
-            getLocation(), ast::ConstantExpr::from_int(
-                               getLocation(), constInit->intValue() + 1));
-    } else {
-        auto untypedThisInit = new ast::UntypedExpr(
-            getLocation(), new ast::NameExpr(getLocation(), "?++"),
-            {prevInitExpr});
-        return new ast::SingleInit(getLocation(), untypedThisInit);
-    }
+	const ast::Init* prev) const {
+	if (prev == nullptr) {
+		return new ast::SingleInit(
+			getLocation(), ast::ConstantExpr::from_int(getLocation(), 0));
+	}
+	auto prevInit = dynamic_cast<const ast::SingleInit*>(prev);
+	assert(prevInit);
+	auto prevInitExpr = prevInit->value;
+	if (auto constInit = prevInitExpr.as<ast::ConstantExpr>()) {
+		// Assume no string literal for now
+		return new ast::SingleInit(
+			getLocation(), ast::ConstantExpr::from_int(
+				getLocation(), constInit->intValue() + 1));
+	} else {
+		auto untypedThisInit = new ast::UntypedExpr(
+			getLocation(), new ast::NameExpr(getLocation(), "?++"),
+			{prevInitExpr});
+		return new ast::SingleInit(getLocation(), untypedThisInit);
+	}
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genProto(
-    std::string&& name, std::vector<ast::ptr<ast::DeclWithType>>&& params,
-    std::vector<ast::ptr<ast::DeclWithType>>&& returns) const {
-    ast::FunctionDecl* decl = new ast::FunctionDecl(
-        // Auto-generated routines use the type declaration's location.
-        getLocation(), std::move(name), {}, {}, std::move(params),
-        std::move(returns),
-        // Only a prototype, no body.
-        nullptr,
-        // Use static storage if we are at the top level.
-        (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static,
-        proto_linkage, std::vector<ast::ptr<ast::Attribute>>(),
-        // Auto-generated routines are inline to avoid conflicts.
-        ast::Function::Specs(ast::Function::Inline));
-    decl->fixUniqueId();
-    return decl;
+	std::string&& name, std::vector<ast::ptr<ast::DeclWithType>>&& params,
+	std::vector<ast::ptr<ast::DeclWithType>>&& returns) const {
+	ast::FunctionDecl* decl = new ast::FunctionDecl(
+		// Auto-generated routines use the type declaration's location.
+		getLocation(), std::move(name), {}, {}, std::move(params),
+		std::move(returns),
+		// Only a prototype, no body.
+		nullptr,
+		// Use static storage if we are at the top level.
+		(0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static,
+		proto_linkage, std::vector<ast::ptr<ast::Attribute>>(),
+		// Auto-generated routines are inline to avoid conflicts.
+		ast::Function::Specs(ast::Function::Inline));
+	decl->fixUniqueId();
+	return decl;
 }
 
 void EnumAttrFuncGenerator::produceDecl(const ast::FunctionDecl* decl) {
-    assert(nullptr != decl->stmts);
-
-    definitions.push_back(decl);
+	assert(nullptr != decl->stmts);
+
+	definitions.push_back(decl);
 }
 
 void EnumAttrFuncGenerator::produceForwardDecl(const ast::FunctionDecl* decl) {
-    if (0 != functionNesting) return;
-    ast::FunctionDecl* fwd =
-        (decl->stmts) ? ast::asForward(decl) : ast::deepCopy(decl);
-    fwd->fixUniqueId();
-    forwards.push_back(fwd);
+	if (0 != functionNesting) return;
+	ast::FunctionDecl* fwd =
+		(decl->stmts) ? ast::asForward(decl) : ast::deepCopy(decl);
+	fwd->fixUniqueId();
+	forwards.push_back(fwd);
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genPosnProto() const {
-    return genProto(
-        "posE",
-        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret",
-            new ast::BasicType(ast::BasicKind::UnsignedInt))});
+	return genProto(
+		"posE",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret",
+			new ast::BasicType(ast::BasicKind::UnsignedInt))});
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genLabelProto() const {
-    return genProto(
-        "labelE",
-        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
-        {new ast::ObjectDecl(
-            getLocation(), "_ret",
-            new ast::PointerType(new ast::BasicType{ast::BasicKind::Char}))});
+	return genProto(
+		"labelE",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(
+			getLocation(), "_ret",
+			new ast::PointerType(new ast::BasicType{ast::BasicKind::Char}))});
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genValueProto() const {
-    return genProto(
-        "valueE",
-        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret",
-                             ast::deepCopy(decl->base))});
+	return genProto(
+		"valueE",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret",
+		                     ast::deepCopy(decl->base))});
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccProto() const {
-    return genProto(
-        "succ",
-        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret",
-                             new ast::EnumInstType(decl))});
+	return genProto(
+		"succ",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret",
+		                     new ast::EnumInstType(decl))});
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genPredProto() const {
-    return genProto(
-        "pred",
-        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret",
-                             new ast::EnumInstType(decl))});
+	return genProto(
+		"pred",
+		{new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret",
+		                     new ast::EnumInstType(decl))});
 }
 
 inline ast::EnumAttrType * getPosnType( const ast::EnumDecl * decl ) {
-    return new ast::EnumAttrType(new ast::EnumInstType(decl), ast::EnumAttribute::Posn);
+	return new ast::EnumAttrType(new ast::EnumInstType(decl), ast::EnumAttribute::Posn);
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccPosProto() const {
-    return genProto(
-        "_successor_",
-        {new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))}
-    );
+	return genProto(
+		"_successor_",
+		{new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))}
+	);
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genPredPosProto() const {
-    return genProto(
-        "_predessor_",
-        {new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))},
-        {new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))}
-    );
+	return genProto(
+		"_predessor_",
+		{new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))},
+		{new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))}
+	);
 }
 
 ast::ObjectDecl* EnumAttrFuncGenerator::genAttrArrayProto(
-    const ast::EnumAttribute attr, const CodeLocation& location,
-    std::vector<ast::ptr<ast::Init>>& inits) const {
-    ast::ArrayType* arrT = new ast::ArrayType(
-        attr == ast::EnumAttribute::Value
-            ? decl->base
-            : new ast::PointerType(new ast::BasicType{ast::BasicKind::Char}),
-        ast::ConstantExpr::from_int(decl->location, decl->members.size()),
-        ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim);
-
-    ast::ObjectDecl* objDecl =
-        new ast::ObjectDecl(decl->location, decl->getUnmangeldArrayName(attr),
-                            arrT, new ast::ListInit(location, std::move(inits)),
-                            ast::Storage::Static, ast::Linkage::AutoGen);
-
-    return objDecl;
+	const ast::EnumAttribute attr, const CodeLocation& location,
+	std::vector<ast::ptr<ast::Init>>& inits) const {
+	ast::ArrayType* arrT = new ast::ArrayType(
+		attr == ast::EnumAttribute::Value
+			? decl->base
+			: new ast::PointerType(new ast::BasicType{ast::BasicKind::Char}),
+		ast::ConstantExpr::from_int(decl->location, decl->members.size()),
+		ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim);
+
+	ast::ObjectDecl* objDecl =
+		new ast::ObjectDecl(
+			decl->location, decl->getUnmangeldArrayName( attr ),
+			arrT, new ast::ListInit( location, std::move( inits ) ),
+			ast::Storage::Static, ast::Linkage::AutoGen );
+
+	return objDecl;
 }
 
 void EnumAttrFuncGenerator::genValueOrLabelBody(
-    ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const {
-    ast::UntypedExpr* untyped = ast::UntypedExpr::createCall(
-        func->location, "?[?]",
-        {new ast::NameExpr(func->location, arrDecl->name),
-         new ast::CastExpr(
-             func->location,
-             new ast::VariableExpr(func->location, func->params.front()),
-             new ast::EnumAttrType(new ast::EnumInstType(decl),
-                                   ast::EnumAttribute::Posn))});
-    func->stmts = new ast::CompoundStmt(
-        func->location, {new ast::ReturnStmt(func->location, untyped)});
+	ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const {
+	ast::UntypedExpr* untyped = ast::UntypedExpr::createCall(
+		func->location, "?[?]",
+		{new ast::NameExpr(func->location, arrDecl->name),
+			new ast::CastExpr(
+				func->location,
+				new ast::VariableExpr( func->location, func->params.front() ),
+				new ast::EnumAttrType( new ast::EnumInstType(decl),
+					ast::EnumAttribute::Posn))});
+	func->stmts = new ast::CompoundStmt(
+		func->location, {new ast::ReturnStmt(func->location, untyped)});
 }
 
 void EnumAttrFuncGenerator::genPosnBody(ast::FunctionDecl* func) const {
-    auto castExpr = new ast::CastExpr(
-        func->location,
-        new ast::VariableExpr(func->location, func->params.front()),
-        new ast::EnumAttrType(new ast::EnumInstType(decl),
-                              ast::EnumAttribute::Posn));
-    func->stmts = new ast::CompoundStmt(
-        func->location, {new ast::ReturnStmt(func->location, castExpr)});
+	auto castExpr = new ast::CastExpr(
+		func->location,
+		new ast::VariableExpr(func->location, func->params.front()),
+		new ast::EnumAttrType(new ast::EnumInstType(decl),
+							  ast::EnumAttribute::Posn));
+	func->stmts = new ast::CompoundStmt(
+		func->location, {new ast::ReturnStmt(func->location, castExpr)});
 }
 
 void EnumAttrFuncGenerator::genAttributesDecls(const ast::EnumAttribute attr) {
-    if (attr == ast::EnumAttribute::Value ||
-        attr == ast::EnumAttribute::Label) {
-        std::vector<ast::ptr<ast::Init>> inits =
-            attr == ast::EnumAttribute::Value ? genValueInit() : genLabelInit();
-        ast::ObjectDecl* arrayProto =
-            genAttrArrayProto(attr, getLocation(), inits);
-        forwards.push_back(arrayProto);
-
-        ast::FunctionDecl* funcProto = attr == ast::EnumAttribute::Value
-                                           ? genValueProto()
-                                           : genLabelProto();
-        produceForwardDecl(funcProto);
-        genValueOrLabelBody(funcProto, arrayProto);
-        produceDecl(funcProto);
-    } else {
-        ast::FunctionDecl* funcProto = genPosnProto();
-        produceForwardDecl(funcProto);
-        genPosnBody(funcProto);
-        produceDecl(funcProto);
-    }
+	if (attr == ast::EnumAttribute::Value ||
+		attr == ast::EnumAttribute::Label) {
+		std::vector<ast::ptr<ast::Init>> inits =
+			attr == ast::EnumAttribute::Value ? genValueInit() : genLabelInit();
+		ast::ObjectDecl* arrayProto =
+			genAttrArrayProto(attr, getLocation(), inits);
+		forwards.push_back(arrayProto);
+
+		ast::FunctionDecl* funcProto = ( attr == ast::EnumAttribute::Value )
+		                               ? genValueProto()
+		                               : genLabelProto();
+		produceForwardDecl(funcProto);
+		genValueOrLabelBody(funcProto, arrayProto);
+		produceDecl(funcProto);
+	} else {
+		ast::FunctionDecl* funcProto = genPosnProto();
+		produceForwardDecl(funcProto);
+		genPosnBody(funcProto);
+		produceDecl(funcProto);
+	}
 }
 
 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccPredFunc(bool succ) {
-    ast::FunctionDecl* funcDecl = succ ? genSuccPosProto() : genPredPosProto();
-    produceForwardDecl(funcDecl);
-
-    const CodeLocation& location = getLocation();
-
-    auto& params = funcDecl->params;
-    assert(params.size() == 1);
-    auto param = params.front().strict_as<ast::ObjectDecl>();
-
-
-    auto rets = funcDecl->returns;
-    assert(params.size() == 1);
-    auto ret = rets.front().strict_as<ast::ObjectDecl>();
-    auto retType = ret->type.strict_as<ast::EnumAttrType>();
-
-    auto addOneExpr = ast::UntypedExpr::createCall( location,
-        succ? "?+?": "?-?",
-        {new ast::VariableExpr(location, param),
-        ast::ConstantExpr::from_int(location, 1)}
-    );
-
-    funcDecl->stmts = new ast::CompoundStmt(
-        location, {
-            new ast::ReturnStmt(
-                location, 
-                new ast::CastExpr(location, addOneExpr, retType) 
-            )
-        }
-    );
-
-    return funcDecl;
+	ast::FunctionDecl* funcDecl = succ ? genSuccPosProto() : genPredPosProto();
+	produceForwardDecl(funcDecl);
+
+	const CodeLocation& location = getLocation();
+
+	auto& params = funcDecl->params;
+	assert(params.size() == 1);
+	auto param = params.front().strict_as<ast::ObjectDecl>();
+
+
+	auto rets = funcDecl->returns;
+	assert(params.size() == 1);
+	auto ret = rets.front().strict_as<ast::ObjectDecl>();
+	auto retType = ret->type.strict_as<ast::EnumAttrType>();
+
+	auto addOneExpr = ast::UntypedExpr::createCall( location,
+		succ? "?+?": "?-?",
+		{new ast::VariableExpr(location, param),
+		ast::ConstantExpr::from_int(location, 1)}
+	);
+
+	funcDecl->stmts = new ast::CompoundStmt(
+		location, {
+			new ast::ReturnStmt(
+				location,
+				new ast::CastExpr(location, addOneExpr, retType)
+			)
+		}
+	);
+
+	return funcDecl;
 }
 
 void EnumAttrFuncGenerator::genAttrFunctions() {
-    if (decl->base) {
-        genAttributesDecls(ast::EnumAttribute::Value);
-        genAttributesDecls(ast::EnumAttribute::Label);
-        genAttributesDecls(ast::EnumAttribute::Posn);
-    }
+	if (decl->base) {
+		genAttributesDecls(ast::EnumAttribute::Value);
+		genAttributesDecls(ast::EnumAttribute::Label);
+		genAttributesDecls(ast::EnumAttribute::Posn);
+	}
 }
 
 void EnumAttrFuncGenerator::genSuccPredDecl() {
-    if (decl->base) {
-        auto succProto = genSuccProto();
-        auto predProto = genPredProto();
-
-        produceForwardDecl(succProto);
-        produceForwardDecl(predProto);
-    }
+	if (decl->base) {
+		auto succProto = genSuccProto();
+		auto predProto = genPredProto();
+
+		produceForwardDecl(succProto);
+		produceForwardDecl(predProto);
+	}
 }
 
 void EnumAttrFuncGenerator::genSuccPredPosn() {
-    if (decl->base) {
-        ast::FunctionDecl* succ = genSuccPredFunc(true);
-        ast::FunctionDecl* pred = genSuccPredFunc(false);
-
-        produceDecl(succ);
-        produceDecl(pred);
-    }
+	if (decl->base) {
+		ast::FunctionDecl* succ = genSuccPredFunc(true);
+		ast::FunctionDecl* pred = genSuccPredFunc(false);
+
+		produceDecl(succ);
+		produceDecl(pred);
+	}
 }
 
 void EnumAttrFuncGenerator::generateAndAppendFunctions(
-    std::list<ast::ptr<ast::Decl>>& decls) {
-    // Generate the functions (they go into forwards and definitions).
-    genAttrStandardFuncs();
-    genAttrFunctions();
-    genSuccPredDecl();
-    genSuccPredPosn(); // Posn
-    // Now export the lists contents.
-    decls.splice(decls.end(), forwards);
-    decls.splice(decls.end(), definitions);
+	std::list<ast::ptr<ast::Decl>>& decls) {
+	// Generate the functions (they go into forwards and definitions).
+	genAttrStandardFuncs();
+	genAttrFunctions();
+	genSuccPredDecl();
+	genSuccPredPosn(); // Posn
+	// Now export the lists contents.
+	decls.splice(decls.end(), forwards);
+	decls.splice(decls.end(), definitions);
 }
 
 // ---------------------------------------------------------
 
-struct ImplementEnumFunc final : public ast::WithDeclsToAdd<>,
-                                 public ast::WithShortCircuiting {
-    void previsit(const ast::EnumDecl* enumDecl);
-    void previsit(const ast::FunctionDecl* functionDecl);
-    void postvisit(const ast::FunctionDecl* functionDecl);
-
-   private:
-    // Current level of nested functions.
-    unsigned int functionNesting = 0;
+struct ImplementEnumFunc final :
+		public ast::WithDeclsToAdd<>, public ast::WithShortCircuiting {
+	void previsit(const ast::EnumDecl* enumDecl);
+	void previsit(const ast::FunctionDecl* functionDecl);
+	void postvisit(const ast::FunctionDecl* functionDecl);
+
+private:
+	// Current level of nested functions.
+	unsigned int functionNesting = 0;
 };
 
 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
-    if (!enumDecl->body) return;
-    if (!enumDecl->base) return;
-
-    ast::EnumInstType enumInst(enumDecl->name);
-    enumInst.base = enumDecl;
-
-    EnumAttrFuncGenerator gen(enumDecl, &enumInst, functionNesting);
-    gen.generateAndAppendFunctions(declsToAddAfter);
+	if (!enumDecl->body) return;
+	if (!enumDecl->base) return;
+
+	ast::EnumInstType enumInst(enumDecl->name);
+	enumInst.base = enumDecl;
+
+	EnumAttrFuncGenerator gen(enumDecl, &enumInst, functionNesting);
+	gen.generateAndAppendFunctions(declsToAddAfter);
 }
 
 void ImplementEnumFunc::previsit(const ast::FunctionDecl*) {
-    functionNesting += 1;
+	functionNesting += 1;
 }
 
 void ImplementEnumFunc::postvisit(const ast::FunctionDecl*) {
-    functionNesting -= 1;
-}
-
-}  // namespace
+	functionNesting -= 1;
+}
+
+} // namespace
 
 void implementEnumFunc(ast::TranslationUnit& translationUnit) {
-    ast::Pass<ImplementEnumFunc>::run(translationUnit);
-}
-}  // namespace Validate
+	ast::Pass<ImplementEnumFunc>::run(translationUnit);
+}
+
+} // namespace Validate
Index: src/Virtual/VirtualDtor.cpp
===================================================================
--- src/Virtual/VirtualDtor.cpp	(revision b9b6efb5368046ebaf333ceef3ec7de4bdbda34d)
+++ src/Virtual/VirtualDtor.cpp	(revision fc1a3e283512526d1ddc12898c7c5fa33f0ddeaf)
@@ -28,320 +28,320 @@
 
 struct CtorDtor {
-    FunctionDecl * dtorSetup;  // dtor init routine to add after last dtor for a struct
-    FunctionDecl * deleteFn;
-    FunctionDecl * lastDtor;    // pointer to last occurence of dtor to know where to insert after
-
-    CtorDtor() : dtorSetup(nullptr), deleteFn(nullptr), lastDtor(nullptr) {}
+	FunctionDecl * dtorSetup;  // dtor init routine to add after last dtor for a struct
+	FunctionDecl * deleteFn;
+	FunctionDecl * lastDtor;    // pointer to last occurence of dtor to know where to insert after
+
+	CtorDtor() : dtorSetup(nullptr), deleteFn(nullptr), lastDtor(nullptr) {}
 };
 
 class CtorDtorTable {
-    unordered_map<const StructDecl *, CtorDtor> & structMap;
+	unordered_map<const StructDecl *, CtorDtor> & structMap;
+
+public:
+	// if dtor is last dtor for this decl return the routine to add afterwards
+	// otherwise return nullptr
+	FunctionDecl * getToAddLater( const StructDecl * decl, FunctionDecl * dtor, FunctionDecl ** retDeleteFn ) {
+		auto iter = structMap.find( decl );
+		if ( iter == structMap.end() || iter->second.lastDtor != dtor ) return nullptr; // check if this is needed
+		*retDeleteFn = iter->second.deleteFn;
+		return iter->second.dtorSetup;
+	}
+
+	// return if the dtorSetup field has been defined for this decl
+	bool inTable( const StructDecl * decl ) {
+		auto iter = structMap.find( decl );
+		return iter->second.dtorSetup != nullptr;
+	}
+
+	void addLater( const StructDecl * decl, FunctionDecl * dtorSetup, FunctionDecl * deleteFn ) {
+		auto iter = structMap.find( decl );
+		iter->second.dtorSetup = dtorSetup;
+		iter->second.deleteFn = deleteFn;
+	}
+
+	void addDtor( const StructDecl * decl, FunctionDecl * dtor ) {
+		auto iter = structMap.find( decl );
+		iter->second.lastDtor = dtor;
+	}
+
+	CtorDtorTable( unordered_map<const StructDecl *, CtorDtor> & structMap ) : structMap(structMap) {}
+};
+
+struct CollectStructDecls : public ast::WithGuards {
+	unordered_map<const StructDecl *, CtorDtor> & structDecls;
+	StructDecl * parentDecl;
+	bool insideStruct = false;
+	bool namedDecl = false;
+
+	const StructDecl ** virtualDtor;
+
+	// finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
+	void previsit( const StructDecl * decl ) {
+		if ( !decl->body ) return;
+		if( decl->name == "virtual_dtor" ) {
+			structDecls.emplace( make_pair( decl, CtorDtor() ) );
+			*virtualDtor = decl;
+		} else {
+			GuardValue(insideStruct);
+			insideStruct = true;
+			parentDecl = mutate( decl );
+		}
+	}
+
+	// this catches structs of the form:
+	//     struct derived_type { virtual_dtor a; };
+	// since they should be:
+	//     struct derived_type { inline virtual_dtor; };
+	void previsit ( const ObjectDecl * decl ) {
+		if ( insideStruct && ! decl->name.empty() ) {
+			GuardValue(namedDecl);
+			namedDecl = true;
+		}
+	}
+
+	// this collects the derived actor and message struct decl ptrs
+	void postvisit( const StructInstType * node ) {
+		if ( ! *virtualDtor ) return;
+		if ( insideStruct && !namedDecl ) {
+			auto structIter = structDecls.find( node->aggr() );
+			if ( structIter != structDecls.end() )
+				structDecls.emplace( make_pair( parentDecl, CtorDtor() ) );
+		}
+	}
 
   public:
-    // if dtor is last dtor for this decl return the routine to add afterwards
-    // otherwise return nullptr
-    FunctionDecl * getToAddLater( const StructDecl * decl, FunctionDecl * dtor, FunctionDecl ** retDeleteFn ) {
-        auto iter = structMap.find( decl );
-        if ( iter == structMap.end() || iter->second.lastDtor != dtor ) return nullptr; // check if this is needed
-        *retDeleteFn = iter->second.deleteFn;
-        return iter->second.dtorSetup;
-    }
-
-    // return if the dtorSetup field has been defined for this decl
-    bool inTable( const StructDecl * decl ) {
-        auto iter = structMap.find( decl );
-        return iter->second.dtorSetup != nullptr;
-    }
-
-    void addLater( const StructDecl * decl, FunctionDecl * dtorSetup, FunctionDecl * deleteFn ) {
-        auto iter = structMap.find( decl );
-        iter->second.dtorSetup = dtorSetup;
-        iter->second.deleteFn = deleteFn;
-    }
-
-    void addDtor( const StructDecl * decl, FunctionDecl * dtor ) {
-        auto iter = structMap.find( decl );
-        iter->second.lastDtor = dtor;
-    }
-
-    CtorDtorTable( unordered_map<const StructDecl *, CtorDtor> & structMap ) : structMap(structMap) {}
-};
-
-struct CollectStructDecls : public ast::WithGuards {
-    unordered_map<const StructDecl *, CtorDtor> & structDecls;
-    StructDecl * parentDecl;
-    bool insideStruct = false;
-    bool namedDecl = false;
-
-    const StructDecl ** virtualDtor;
-
-    // finds and sets a ptr to the actor, message, and request structs, which are needed in the next pass
-    void previsit( const StructDecl * decl ) {
-        if ( !decl->body ) return;
-        if( decl->name == "virtual_dtor" ) {
-            structDecls.emplace( make_pair( decl, CtorDtor() ) );
-            *virtualDtor = decl;
-        } else {
-            GuardValue(insideStruct);
-            insideStruct = true;
-            parentDecl = mutate( decl );
-        }
-	}
-
-    // this catches structs of the form:
-    //     struct derived_type { virtual_dtor a; };
-    // since they should be:
-    //     struct derived_type { inline virtual_dtor; };
-    void previsit ( const ObjectDecl * decl ) {
-        if ( insideStruct && ! decl->name.empty() ) {
-            GuardValue(namedDecl);
-            namedDecl = true;
-        }
-    }
-
-    // this collects the derived actor and message struct decl ptrs
-    void postvisit( const StructInstType * node ) {
-        if ( ! *virtualDtor ) return;
-        if ( insideStruct && !namedDecl ) {
-            auto structIter = structDecls.find( node->aggr() );    
-            if ( structIter != structDecls.end() )
-                structDecls.emplace( make_pair( parentDecl, CtorDtor() ) );
-        }
-	}
-
-  public:
-    CollectStructDecls( unordered_map<const StructDecl *, CtorDtor> & structDecls, const StructDecl ** virtualDtor ):
-        structDecls( structDecls ), virtualDtor(virtualDtor) {}
+	CollectStructDecls( unordered_map<const StructDecl *, CtorDtor> & structDecls, const StructDecl ** virtualDtor ):
+		structDecls( structDecls ), virtualDtor(virtualDtor) {}
 };
 
 // generates the forward decl of virtual dtor setting routine and delete routine
 // generates the call to the virtual dtor routine in each appropriate ctor
-// collects data needed for next pass that does the circular defn resolution 
+// collects data needed for next pass that does the circular defn resolution
 //     for dtor setters and delete fns (via table above)
 struct GenFuncsCreateTables : public ast::WithDeclsToAdd<> {
-    unordered_map<const StructDecl *, CtorDtor> & structDecls;
-    CtorDtorTable & torDecls;
-    const StructDecl ** virtualDtor;
-
-    // collects the dtor info for actors/messages
-    // gens the dtor fwd decl and dtor call in ctor
-    void previsit( const FunctionDecl * decl ) {
-        if ( (decl->name != "?{}" && decl->name != "^?{}") || decl->params.size() == 0 
-            || !decl->stmts || (decl->name == "^?{}" && decl->params.size() != 1)) return;
-
-        // the first param should be a reference
-        const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
-        if ( !ref ) return;
-
-        // the reference should be to a struct instance
-        const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
-        if ( !instType ) return;
-
-        // return if not ctor/dtor for an actor or message
-        auto structIter = structDecls.find( instType->aggr() );
-        if ( structIter == structDecls.end() ) return;
-
-        // If first param not named we need to name it to use it
-        if ( decl->params.at(0)->name == "" )
-            mutate( decl->params.at(0).get() )->name = "__CFA_Virt_Dtor_param";
-
-        if ( decl->name == "^?{}") {
-            torDecls.addDtor( structIter->first, mutate( decl ) );
-
-            CompoundStmt * dtorBody = mutate( decl->stmts.get() );
-            // Adds the following to the start of any actor/message dtor:
-            //  __CFA_dtor_shutdown( this );
-            dtorBody->push_front( 
-                new IfStmt( decl->location,
-                    new UntypedExpr (
-                        decl->location,
-                        new NameExpr( decl->location, "__CFA_dtor_shutdown" ),
-                        {
-                            new NameExpr( decl->location, decl->params.at(0)->name )
-                        }
-                    ),
-                    new ReturnStmt( decl->location, nullptr )
-                )
-            );
-            return;
-        }
-
-        // not dtor by this point so must be ctor
-        CompoundStmt * ctorBody = mutate( decl->stmts.get() );
-        // Adds the following to the end of any actor/message ctor:
-        //  __CFA_set_dtor( this );
-        ctorBody->push_back( new ExprStmt(
-            decl->location,
-            new UntypedExpr (
-                decl->location,
-                new NameExpr( decl->location, "__CFA_set_dtor" ),
-                {
-                    new NameExpr( decl->location, decl->params.at(0)->name )
-                }
-            )
-        ));
-        
-        if ( torDecls.inTable( structIter->first ) ) return;
-
-        // Generates the following:
-        // void __CFA_set_dtor( Derived_type & this ){
-        //     void (*__my_dtor)( Derived_type & ) = ^?{};
-        //     this.__virtual_dtor = (void (*)( Base_type & ))__my_dtor;
-        //     this.__virtual_obj_start = (void *)(&this);
-        // }
-        CompoundStmt * setDtorBody = new CompoundStmt( decl->location );
-
-        // Function type is: (void (*)(Derived_type &))
-        FunctionType * derivedDtor = new FunctionType();
-        derivedDtor->params.push_back( ast::deepCopy( ref ) );
-
-        // Generates:
-        //      void (*__my_dtor)( Derived_type & ) = ^?{};
-        setDtorBody->push_back( new DeclStmt(
-            decl->location,
-            new ObjectDecl(
-                decl->location,
-                "__my_dtor",
-                new PointerType( derivedDtor ),
-                new SingleInit( decl->location, new NameExpr( decl->location, "^?{}" ) )
-            )
-        ));
-
-        // Function type is: (void (*)( Base_type & ))
-        FunctionType * baseDtor = new FunctionType();
-        baseDtor->params.push_back( new ReferenceType( new StructInstType( *virtualDtor ) ) );
-
-        // Generates:
-        //     __CFA_set_virt_dtor( this, (void (*)( Base_type & ))__my_dtor )
-        setDtorBody->push_back( new ExprStmt(
-            decl->location,
-            new UntypedExpr (
-                decl->location,
-                new NameExpr( decl->location, "__CFA_set_virt_dtor" ),
-                {
-                    new NameExpr( decl->location, "this" ),
-                    new CastExpr( decl->location, new NameExpr( decl->location, "__my_dtor" ), new PointerType( baseDtor ), ExplicitCast )
-                }
-            )
-        ));
-
-        // Generates:
-        //     __CFA_set_virt_start( (void *)(&this) );
-        setDtorBody->push_back( new ExprStmt(
-            decl->location,
-            new UntypedExpr (
-                decl->location, 
-                new NameExpr( decl->location, "__CFA_set_virt_start" ),
-                {
-                    new NameExpr( decl->location, "this" ),
-                    new CastExpr(
-                        decl->location, 
-                        new AddressExpr( decl->location, new NameExpr( decl->location, "this" )), 
-                        new PointerType( new ast::VoidType() ), ExplicitCast
-                        )
-                }
-            )
-        ));
-
-        // put it all together into the complete function decl from above
-        FunctionDecl * setDtorFunction = new FunctionDecl(
-            decl->location,
-            "__CFA_set_dtor",
-            {
-                new ObjectDecl(
-                    decl->location,
-                    "this",
-                    ast::deepCopy( ref )
-                ),
-            },                      // params
-            {},
-            nullptr,               // body
-            { Storage::Static },    // storage
-            Linkage::Cforall,       // linkage
-            {},                     // attributes
-            { Function::Inline }
-        );
-
-        declsToAddBefore.push_back( ast::deepCopy( setDtorFunction ) );
-
-        setDtorFunction->stmts = setDtorBody;
-
-        // The following generates the following specialized delete routine:
-        // static inline void delete( derived_type * ptr ) {
-        //     if ( ptr )
-        //         ^(*ptr){};
-        //     __CFA_virt_free( *ptr );
-        // }
-        CompoundStmt * deleteFnBody = new CompoundStmt( decl->location );
-
-        // Generates:
-        //     if ( ptr )
-        //         ^(*ptr){};
-        deleteFnBody->push_back(
-            new IfStmt(
-                decl->location,
-                UntypedExpr::createCall(
-                    decl->location,
-                    "?!=?",
-                    {
-                        new NameExpr( decl->location, "ptr" ),
-                        ConstantExpr::null( decl->location, new PointerType( ast::deepCopy( instType ) ) )
-                    }
-                ),
-                new ExprStmt(
-                    decl->location,
-                    UntypedExpr::createCall( 
-                        decl->location, 
-                        "^?{}",
-                        {
-                            UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
-                        }
-                    )
-                )
-            )
-        );
-
-        // Generates:
-        //     __CFA_virt_free( *ptr );
-        deleteFnBody->push_back( new ExprStmt(
-                decl->location,
-                UntypedExpr::createCall( 
-                    decl->location, 
-                    "__CFA_virt_free",
-                    {
-                        UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
-                    }
-                )
-            )
-        );
-
-        FunctionDecl * deleteFn = new FunctionDecl(
-            decl->location,
-            "delete",
-            {
-                new ObjectDecl(
-                    decl->location,
-                    "ptr",
-                    new PointerType( ast::deepCopy( instType ) )
-                ),
-            },                      // params
-            {},
-            nullptr,               // body
-            { Storage::Static },    // storage
-            Linkage::Cforall,       // linkage
-            {},                     // attributes
-            { Function::Inline }
-        );
-
-        declsToAddBefore.push_back( ast::deepCopy( deleteFn ) );
-
-        deleteFn->stmts = deleteFnBody;
-
-        torDecls.addLater( structIter->first, setDtorFunction, deleteFn );
-    }
+	unordered_map<const StructDecl *, CtorDtor> & structDecls;
+	CtorDtorTable & torDecls;
+	const StructDecl ** virtualDtor;
+
+	// collects the dtor info for actors/messages
+	// gens the dtor fwd decl and dtor call in ctor
+	void previsit( const FunctionDecl * decl ) {
+		if ( (decl->name != "?{}" && decl->name != "^?{}") || decl->params.size() == 0
+			|| !decl->stmts || (decl->name == "^?{}" && decl->params.size() != 1)) return;
+
+		// the first param should be a reference
+		const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
+		if ( !ref ) return;
+
+		// the reference should be to a struct instance
+		const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
+		if ( !instType ) return;
+
+		// return if not ctor/dtor for an actor or message
+		auto structIter = structDecls.find( instType->aggr() );
+		if ( structIter == structDecls.end() ) return;
+
+		// If first param not named we need to name it to use it
+		if ( decl->params.at(0)->name == "" )
+			mutate( decl->params.at(0).get() )->name = "__CFA_Virt_Dtor_param";
+
+		if ( decl->name == "^?{}") {
+			torDecls.addDtor( structIter->first, mutate( decl ) );
+
+			CompoundStmt * dtorBody = mutate( decl->stmts.get() );
+			// Adds the following to the start of any actor/message dtor:
+			//  __CFA_dtor_shutdown( this );
+			dtorBody->push_front(
+				new IfStmt( decl->location,
+					new UntypedExpr (
+						decl->location,
+						new NameExpr( decl->location, "__CFA_dtor_shutdown" ),
+						{
+							new NameExpr( decl->location, decl->params.at(0)->name )
+						}
+					),
+					new ReturnStmt( decl->location, nullptr )
+				)
+			);
+			return;
+		}
+
+		// not dtor by this point so must be ctor
+		CompoundStmt * ctorBody = mutate( decl->stmts.get() );
+		// Adds the following to the end of any actor/message ctor:
+		//  __CFA_set_dtor( this );
+		ctorBody->push_back( new ExprStmt(
+			decl->location,
+			new UntypedExpr (
+				decl->location,
+				new NameExpr( decl->location, "__CFA_set_dtor" ),
+				{
+					new NameExpr( decl->location, decl->params.at(0)->name )
+				}
+			)
+		));
+
+		if ( torDecls.inTable( structIter->first ) ) return;
+
+		// Generates the following:
+		// void __CFA_set_dtor( Derived_type & this ){
+		//     void (*__my_dtor)( Derived_type & ) = ^?{};
+		//     this.__virtual_dtor = (void (*)( Base_type & ))__my_dtor;
+		//     this.__virtual_obj_start = (void *)(&this);
+		// }
+		CompoundStmt * setDtorBody = new CompoundStmt( decl->location );
+
+		// Function type is: (void (*)(Derived_type &))
+		FunctionType * derivedDtor = new FunctionType();
+		derivedDtor->params.push_back( ast::deepCopy( ref ) );
+
+		// Generates:
+		//      void (*__my_dtor)( Derived_type & ) = ^?{};
+		setDtorBody->push_back( new DeclStmt(
+			decl->location,
+			new ObjectDecl(
+				decl->location,
+				"__my_dtor",
+				new PointerType( derivedDtor ),
+				new SingleInit( decl->location, new NameExpr( decl->location, "^?{}" ) )
+			)
+		));
+
+		// Function type is: (void (*)( Base_type & ))
+		FunctionType * baseDtor = new FunctionType();
+		baseDtor->params.push_back( new ReferenceType( new StructInstType( *virtualDtor ) ) );
+
+		// Generates:
+		//     __CFA_set_virt_dtor( this, (void (*)( Base_type & ))__my_dtor )
+		setDtorBody->push_back( new ExprStmt(
+			decl->location,
+			new UntypedExpr (
+				decl->location,
+				new NameExpr( decl->location, "__CFA_set_virt_dtor" ),
+				{
+					new NameExpr( decl->location, "this" ),
+					new CastExpr( decl->location, new NameExpr( decl->location, "__my_dtor" ), new PointerType( baseDtor ), ExplicitCast )
+				}
+			)
+		));
+
+		// Generates:
+		//     __CFA_set_virt_start( (void *)(&this) );
+		setDtorBody->push_back( new ExprStmt(
+			decl->location,
+			new UntypedExpr (
+				decl->location,
+				new NameExpr( decl->location, "__CFA_set_virt_start" ),
+				{
+					new NameExpr( decl->location, "this" ),
+					new CastExpr(
+						decl->location,
+						new AddressExpr( decl->location, new NameExpr( decl->location, "this" )),
+						new PointerType( new ast::VoidType() ), ExplicitCast
+						)
+				}
+			)
+		));
+
+		// put it all together into the complete function decl from above
+		FunctionDecl * setDtorFunction = new FunctionDecl(
+			decl->location,
+			"__CFA_set_dtor",
+			{
+				new ObjectDecl(
+					decl->location,
+					"this",
+					ast::deepCopy( ref )
+				),
+			},                      // params
+			{},
+			nullptr,               // body
+			{ Storage::Static },    // storage
+			Linkage::Cforall,       // linkage
+			{},                     // attributes
+			{ Function::Inline }
+		);
+
+		declsToAddBefore.push_back( ast::deepCopy( setDtorFunction ) );
+
+		setDtorFunction->stmts = setDtorBody;
+
+		// The following generates the following specialized delete routine:
+		// static inline void delete( derived_type * ptr ) {
+		//     if ( ptr )
+		//         ^(*ptr){};
+		//     __CFA_virt_free( *ptr );
+		// }
+		CompoundStmt * deleteFnBody = new CompoundStmt( decl->location );
+
+		// Generates:
+		//     if ( ptr )
+		//         ^(*ptr){};
+		deleteFnBody->push_back(
+			new IfStmt(
+				decl->location,
+				UntypedExpr::createCall(
+					decl->location,
+					"?!=?",
+					{
+						new NameExpr( decl->location, "ptr" ),
+						ConstantExpr::null( decl->location, new PointerType( ast::deepCopy( instType ) ) )
+					}
+				),
+				new ExprStmt(
+					decl->location,
+					UntypedExpr::createCall(
+						decl->location,
+						"^?{}",
+						{
+							UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
+						}
+					)
+				)
+			)
+		);
+
+		// Generates:
+		//     __CFA_virt_free( *ptr );
+		deleteFnBody->push_back( new ExprStmt(
+				decl->location,
+				UntypedExpr::createCall(
+					decl->location,
+					"__CFA_virt_free",
+					{
+						UntypedExpr::createDeref( decl->location, new NameExpr( decl->location, "ptr" ))
+					}
+				)
+			)
+		);
+
+		FunctionDecl * deleteFn = new FunctionDecl(
+			decl->location,
+			"delete",
+			{
+				new ObjectDecl(
+					decl->location,
+					"ptr",
+					new PointerType( ast::deepCopy( instType ) )
+				),
+			},                      // params
+			{},
+			nullptr,               // body
+			{ Storage::Static },    // storage
+			Linkage::Cforall,       // linkage
+			{},                     // attributes
+			{ Function::Inline }
+		);
+
+		declsToAddBefore.push_back( ast::deepCopy( deleteFn ) );
+
+		deleteFn->stmts = deleteFnBody;
+
+		torDecls.addLater( structIter->first, setDtorFunction, deleteFn );
+	}
 
   public:
-    GenFuncsCreateTables( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls, const StructDecl ** virtualDtor ):
-    structDecls(structDecls), torDecls(torDecls), virtualDtor(virtualDtor) {}
+	GenFuncsCreateTables( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls, const StructDecl ** virtualDtor ):
+	structDecls(structDecls), torDecls(torDecls), virtualDtor(virtualDtor) {}
 };
 
@@ -349,55 +349,54 @@
 // generates the trailing definitions of dtor setting routines for virtual dtors on messages and actors
 // generates the function defns of __CFA_set_dtor
-// separate pass is needed since  __CFA_set_dtor needs to be defined after 
+// separate pass is needed since  __CFA_set_dtor needs to be defined after
 //   the last dtor defn which is found in prior pass
 struct GenSetDtor : public ast::WithDeclsToAdd<> {
-    unordered_map<const StructDecl *, CtorDtor> & structDecls; // set of decls that inherit from virt dtor
-    CtorDtorTable & torDecls;
-
-    // handles adding the declaration of the dtor init routine after the last dtor detected
-    void postvisit( const FunctionDecl * decl ) {
-        if ( decl->name != "^?{}" || !decl->stmts || decl->params.size() != 1 ) return;
-
-        // the one param should be a reference
-        const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
-        if ( !ref ) return;
-
-        // the reference should be to a struct instance
-        const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
-        if ( !instType ) return;
-
-        FunctionDecl * deleteRtn;
-
-        // returns nullptr if not in table
-        FunctionDecl * maybeAdd = torDecls.getToAddLater( instType->aggr(), mutate( decl ), &deleteRtn );
-        if ( maybeAdd ) {
-            declsToAddAfter.push_back( maybeAdd );
-            declsToAddAfter.push_back( deleteRtn );
-        }
-    }
-
-  public:
-    GenSetDtor( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls ):
-        structDecls(structDecls), torDecls(torDecls) {}
+	unordered_map<const StructDecl *, CtorDtor> & structDecls; // set of decls that inherit from virt dtor
+	CtorDtorTable & torDecls;
+
+	// handles adding the declaration of the dtor init routine after the last dtor detected
+	void postvisit( const FunctionDecl * decl ) {
+		if ( decl->name != "^?{}" || !decl->stmts || decl->params.size() != 1 ) return;
+
+		// the one param should be a reference
+		const ReferenceType * ref = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
+		if ( !ref ) return;
+
+		// the reference should be to a struct instance
+		const StructInstType * instType = dynamic_cast<const StructInstType *>(ref->base.get());
+		if ( !instType ) return;
+
+		FunctionDecl * deleteRtn;
+
+		// returns nullptr if not in table
+		FunctionDecl * maybeAdd = torDecls.getToAddLater( instType->aggr(), mutate( decl ), &deleteRtn );
+		if ( maybeAdd ) {
+			declsToAddAfter.push_back( maybeAdd );
+			declsToAddAfter.push_back( deleteRtn );
+		}
+	}
+
+public:
+	GenSetDtor( unordered_map<const StructDecl *, CtorDtor> & structDecls, CtorDtorTable & torDecls ):
+		structDecls(structDecls), torDecls(torDecls) {}
 };
 
 void implementVirtDtors( TranslationUnit & translationUnit ) {
-    // unordered_map to collect all derived types and associated data
-    unordered_map<const StructDecl *, CtorDtor> structDecls;
-    CtorDtorTable torDecls( structDecls );
-
-    const StructDecl * virtualDtorPtr = nullptr;
-    const StructDecl ** virtualDtor = &virtualDtorPtr;
-
-    // first pass collects all structs that inherit from virtual_dtor
-    Pass<CollectStructDecls>::run( translationUnit, structDecls, virtualDtor );
-
-    // second pass locates all dtor/ctor routines that need modifying or need fns inserted before/after
-    Pass<GenFuncsCreateTables>::run( translationUnit, structDecls, torDecls, virtualDtor );
-
-    // The third pass adds the forward decls needed to resolve circular defn problems
-    Pass<GenSetDtor>::run( translationUnit, structDecls, torDecls );
+	// unordered_map to collect all derived types and associated data
+	unordered_map<const StructDecl *, CtorDtor> structDecls;
+	CtorDtorTable torDecls( structDecls );
+
+	const StructDecl * virtualDtorPtr = nullptr;
+	const StructDecl ** virtualDtor = &virtualDtorPtr;
+
+	// first pass collects all structs that inherit from virtual_dtor
+	Pass<CollectStructDecls>::run( translationUnit, structDecls, virtualDtor );
+
+	// second pass locates all dtor/ctor routines that need modifying or need fns inserted before/after
+	Pass<GenFuncsCreateTables>::run( translationUnit, structDecls, torDecls, virtualDtor );
+
+	// The third pass adds the forward decls needed to resolve circular defn problems
+	Pass<GenSetDtor>::run( translationUnit, structDecls, torDecls );
 }
-
 
 } // namespace Virtual
