Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/Parser/DeclarationNode.cc	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb 23 15:45:02 2017
-// Update Count     : 759
+// Last Modified On : Thu Feb 23 22:21:06 2017
+// Update Count     : 775
 //
 
@@ -607,5 +607,8 @@
 					type->aggInst.aggregate = o->type;
 					if ( o->type->kind == TypeData::Aggregate ) {
+						type->aggInst.hoistType = o->type->aggregate.body;
 						type->aggInst.params = maybeClone( o->type->aggregate.actuals );
+					} else {
+						type->aggInst.hoistType = o->type->enumeration.body;
 					} // if
 					type->qualifiers |= o->type->qualifiers;
@@ -881,4 +884,6 @@
 				newType->aggInst.aggregate->aggregate.fields = nullptr;
 			} // if
+			// don't hoist twice
+			newType->aggInst.hoistType = false;
 		} // if
 
@@ -941,5 +946,5 @@
 	SemanticError errors;
 	std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
-	
+
 	for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
 		try {
@@ -953,5 +958,5 @@
 					auto obj = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, nullptr, inst, nullptr );
 					obj->location = cur->location;
-					* out++ = obj; 
+					* out++ = obj;
 					delete agg;
 				} else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
@@ -1035,46 +1040,7 @@
 
 	switch ( type->kind ) {
-	  case TypeData::Enum: {
-		  if ( type->enumeration.body ) {
-			  EnumDecl * typedecl = buildEnum( type, attributes );
-			  return new EnumInstType( buildQualifiers( type ), typedecl );
-		  } else {
-			  return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
-		  }
-	  }
+	  case TypeData::Enum:
 	  case TypeData::Aggregate: {
-		  ReferenceToType * ret;
-		  if ( type->aggregate.body ) {
-			  AggregateDecl * typedecl = buildAggregate( type, attributes );
-			  switch ( type->aggregate.kind ) {
-				case DeclarationNode::Struct:
-				  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
-				  break;
-				case DeclarationNode::Union:
-				  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
-				  break;
-				case DeclarationNode::Trait:
-				  assert( false );
-				  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
-				  break;
-				default:
-				  assert( false );
-			  } // switch
-		  } else {
-			  switch ( type->aggregate.kind ) {
-				case DeclarationNode::Struct:
-				  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
-				  break;
-				case DeclarationNode::Union:
-				  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
-				  break;
-				case DeclarationNode::Trait:
-				  assert( false );
-				  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
-				  break;
-				default:
-				  assert( false );
-			  } // switch
-		  } // if
+		  ReferenceToType * ret = buildComAggInst( type, attributes );
 		  buildList( type->aggregate.actuals, ret->get_parameters() );
 		  return ret;
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/Parser/TypeData.cc	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:12:51 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb 23 16:26:39 2017
-// Update Count     : 477
+// Last Modified On : Thu Feb 23 21:48:55 2017
+// Update Count     : 485
 //
 
@@ -62,4 +62,5 @@
 		aggInst.aggregate = nullptr;
 		aggInst.params = nullptr;
+		aggInst.hoistType = false;;
 		break;
 	  case Enum:
@@ -195,4 +196,5 @@
 		newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
 		newtype->aggInst.params = maybeClone( aggInst.params );
+		newtype->aggInst.hoistType = aggInst.hoistType;
 		break;
 	  case Enum:
@@ -644,27 +646,85 @@
 } // buildAggregate
 
+ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes ) {
+	switch ( type->kind ) {
+	  case TypeData::Enum: {
+		  if ( type->enumeration.body ) {
+			  EnumDecl * typedecl = buildEnum( type, attributes );
+			  return new EnumInstType( buildQualifiers( type ), typedecl );
+		  } else {
+			  return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
+		  } // if
+	  }
+	  case TypeData::Aggregate: {
+		  ReferenceToType * ret;
+		  if ( type->aggregate.body ) {
+			  AggregateDecl * typedecl = buildAggregate( type, attributes );
+			  switch ( type->aggregate.kind ) {
+				case DeclarationNode::Struct:
+				  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
+				  break;
+				case DeclarationNode::Union:
+				  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
+				  break;
+				case DeclarationNode::Trait:
+				  assert( false );
+				  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
+				  break;
+				default:
+				  assert( false );
+			  } // switch
+		  } else {
+			  switch ( type->aggregate.kind ) {
+				case DeclarationNode::Struct:
+				  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
+				  break;
+				case DeclarationNode::Union:
+				  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
+				  break;
+				case DeclarationNode::Trait:
+				  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
+				  break;
+				default:
+				  assert( false );
+			  } // switch
+		  } // if
+		  return ret;
+	  }
+	  default:
+		assert( false );
+	} // switch
+} // buildAggInst
+
 ReferenceToType * buildAggInst( const TypeData * td ) {
 	assert( td->kind == TypeData::AggregateInst );
 
-	ReferenceToType * ret;
-	if ( td->aggInst.aggregate->kind == TypeData::Enum ) {
-		ret = new EnumInstType( buildQualifiers( td ), *td->aggInst.aggregate->enumeration.name );
-	} else {
-		assert( td->aggInst.aggregate->kind == TypeData::Aggregate );
-		switch ( td->aggInst.aggregate->aggregate.kind ) {
-		  case DeclarationNode::Struct:
-			assert( td->aggInst.aggregate->aggregate.name );
-			ret = new StructInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
-			break;
-		  case DeclarationNode::Union:
-			ret = new UnionInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
-			break;
-		  case DeclarationNode::Trait:
-			ret = new TraitInstType( buildQualifiers( td ), *td->aggInst.aggregate->aggregate.name );
-			break;
-		  default:
-			assert( false );
-		} // switch
-	} // if
+	// ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
+	ReferenceToType * ret = nullptr;
+	TypeData * type = td->aggInst.aggregate;
+	switch ( type->kind ) {
+	  case TypeData::Enum: {
+		  return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
+	  }
+	  case TypeData::Aggregate: {
+		  switch ( type->aggregate.kind ) {
+			case DeclarationNode::Struct:
+			  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
+			  break;
+			case DeclarationNode::Union:
+			  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
+			  break;
+			case DeclarationNode::Trait:
+			  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
+			  break;
+			default:
+			  assert( false );
+		  } // switch
+	  }
+	  break;
+	  default:
+		assert( false );
+	} // switch
+
+	ret->set_hoistType( td->aggInst.hoistType );
 	buildList( td->aggInst.params, ret->get_parameters() );
 	buildForall( td->forall, ret->get_forall() );
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/Parser/TypeData.h	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:18:36 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb 23 15:16:18 2017
-// Update Count     : 155
+// Last Modified On : Thu Feb 23 17:14:46 2017
+// Update Count     : 158
 //
 
@@ -38,4 +38,5 @@
 		TypeData * aggregate;
 		ExpressionNode * params;
+		bool hoistType;
 	};
 
@@ -104,4 +105,5 @@
 ArrayType * buildArray( const TypeData * );
 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > );
+ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes );
 ReferenceToType * buildAggInst( const TypeData * );
 NamedTypeDecl * buildSymbolic( const TypeData *, const std::string &name, DeclarationNode::StorageClass sc );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/SymTab/Validate.cc	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:50:04 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb  2 17:47:54 2017
-// Update Count     : 312
+// Last Modified On : Thu Feb 23 21:33:55 2017
+// Update Count     : 318
 //
 
@@ -629,5 +629,5 @@
 		} else {
 			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
-			assertf( base != typedeclNames.end(), "Can't find name %s", typeInst->get_name().c_str() );
+			assertf( base != typedeclNames.end(), "Can't find typedecl name %s", typeInst->get_name().c_str() );
 			typeInst->set_baseType( base->second );
 		} // if
@@ -660,7 +660,7 @@
 		// Note, qualifiers on the typedef are superfluous for the forward declaration.
 		if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( tyDecl->get_base() ) ) {
-			return new StructDecl( aggDecl->get_name() );
+			return aggDecl->get_baseStruct() ? Mutator::mutate( aggDecl->get_baseStruct() ) : new StructDecl( aggDecl->get_name() );
 		} else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
-			return new UnionDecl( aggDecl->get_name() );
+			return aggDecl->get_baseUnion() ? Mutator::mutate( aggDecl->get_baseUnion() ) : new UnionDecl( aggDecl->get_name() );
 		} else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( tyDecl->get_base() ) ) {
 			return new EnumDecl( enumDecl->get_name() );
@@ -732,5 +732,5 @@
 	}
 
-	// there may be typedefs nested within aggregates in order for everything to work properly, these should be removed
+	// there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed
 	// as well
 	template<typename AggDecl>
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/SynTree/ReferenceToType.cc	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb  2 17:45:07 2017
-// Update Count     : 23
+// Last Modified On : Thu Feb 23 16:38:54 2017
+// Update Count     : 24
 //
 
@@ -23,8 +23,8 @@
 #include "Common/utility.h"
 
-ReferenceToType::ReferenceToType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), name( name ) {
+ReferenceToType::ReferenceToType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), name( name ), hoistType( false ) {
 }
 
-ReferenceToType::ReferenceToType( const ReferenceToType &other ) : Type( other ), name( other.name ) {
+ReferenceToType::ReferenceToType( const ReferenceToType &other ) : Type( other ), name( other.name ), hoistType( other.hoistType ) {
 	cloneAll( other.parameters, parameters );
 }
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 24cde55896b292c3bb610ade3c9b9286c0c7a9f9)
+++ src/SynTree/Type.h	(revision 43c89a78fd93abc599e03ce30605af5a82c4e1cc)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb  2 17:43:01 2017
-// Update Count     : 33
+// Last Modified On : Thu Feb 23 16:38:53 2017
+// Update Count     : 34
 //
 
@@ -240,4 +240,6 @@
 	void set_name( std::string newValue ) { name = newValue; }
 	std::list< Expression* >& get_parameters() { return parameters; }
+	bool get_hoistType() const { return hoistType; }
+	void set_hoistType( bool newValue ) { hoistType = newValue; }
 
 	virtual ReferenceToType *clone() const = 0;
@@ -250,4 +252,5 @@
 	std::string name;
   private:
+	bool hoistType;
 };
 
