Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/Box.cc	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -275,5 +275,5 @@
 
 		for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
-			if ( (*decl)->get_kind() == TypeDecl::Any ) {
+			if ( (*decl)->isComplete() ) {
 				otypeDecls.push_back( *decl );
 			}
@@ -719,5 +719,5 @@
 
 		TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
-			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+			addToTyVarMap( typeDecl, scopeTyVars );
 			return Mutator::mutate( typeDecl );
 		}
@@ -774,5 +774,5 @@
 				ResolvExpr::EqvClass eqvClass;
 				assert( env );
-				if ( tyParm->second == TypeDecl::Any ) {
+				if ( tyParm->second.isComplete ) {
 					Type *concrete = env->lookup( tyParm->first );
 					if ( concrete ) {
@@ -1278,5 +1278,5 @@
 			std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
 
-			TyVarMap exprTyVars( (TypeDecl::Kind)-1 );
+			TyVarMap exprTyVars( TypeDecl::Data{} );
 			makeTyVarMap( function, exprTyVars );
 			ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
@@ -1428,4 +1428,5 @@
 
 						// skip non-otype parameters (ftype/dtype)
+						// xxx - should this check whether the type is complete instead?
 						if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
 
@@ -1553,5 +1554,5 @@
 
 		TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
-			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+			addToTyVarMap( typeDecl, scopeTyVars );
 			if ( typeDecl->get_base() ) {
 				return handleDecl( typeDecl, typeDecl->get_base() );
@@ -1597,5 +1598,5 @@
 				ObjectDecl *sizeParm, *alignParm;
 				// add all size and alignment parameters to parameter list
-				if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
+				if ( (*tyParm)->isComplete() ) {
 					TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
 					std::string parmName = mangleType( &parmType );
@@ -1706,5 +1707,5 @@
 
 		TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {
-			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+			addToTyVarMap( typeDecl, scopeTyVars );
 			return Parent::mutate( typeDecl );
 		}
@@ -1870,5 +1871,5 @@
 			for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {
 				// skip non-otype parameters
-				if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue;
+				if ( ! (*baseParam)->isComplete() ) continue;
 				TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );
 				assert( typeExpr && "all otype parameters should be type expressions" );
@@ -2082,5 +2083,5 @@
 //   Initializer *init = 0;
 //   std::list< Expression *> designators;
-//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+//   addToTyVarMap( typeDecl, scopeTyVars );
 //   if ( typeDecl->get_base() ) {
 //     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
@@ -2088,5 +2089,5 @@
 //   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
 
-			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+			addToTyVarMap( typeDecl, scopeTyVars );
 			return Mutator::mutate( typeDecl );
 		}
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/GenPoly.cc	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -97,5 +97,5 @@
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
 			auto var = tyVars.find( typeInst->get_name() );
-			if ( var != tyVars.end() && var->second == TypeDecl::Any ) {
+			if ( var != tyVars.end() && var->second.isComplete ) {
 				return typeInst;
 			}
@@ -117,5 +117,5 @@
 		if ( function->get_returnVals().empty() ) return 0;
 
-		TyVarMap forallTypes( (TypeDecl::Kind)-1 );
+		TyVarMap forallTypes( TypeDecl::Data{} );
 		makeTyVarMap( function, forallTypes );
 		return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
@@ -227,8 +227,12 @@
 	}
 
+	void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
+		tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
+	}
+
 	void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
 		for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
 			assert( *tyVar );
-			tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
+			addToTyVarMap( *tyVar, tyVarMap );
 		}
 		if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/GenPoly.h	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -30,5 +30,5 @@
 
 namespace GenPoly {
-	typedef ErasableScopedMap< std::string, TypeDecl::Kind > TyVarMap;
+	typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;
 
 	/// Replaces a TypeInstType by its referrent in the environment, if applicable
@@ -74,4 +74,7 @@
 	VariableExpr *getBaseVar( Expression *expr, int *levels = 0 );
 
+	/// Adds the type variable `tyVar` to `tyVarMap`
+	void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
+
 	/// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
 	void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/InstantiateGeneric.cc	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -284,4 +284,5 @@
 				// set concDecl to new type, insert type declaration into statements to add
 				concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
+				concDecl->set_body( inst->get_baseStruct()->has_body() );
 				substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, 	concDecl->get_members() );
 				DeclMutator::addDeclaration( concDecl );
@@ -337,4 +338,5 @@
 				// set concDecl to new type, insert type declaration into statements to add
 				concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
+				concDecl->set_body( inst->get_baseUnion()->has_body() );
 				substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
 				DeclMutator::addDeclaration( concDecl );
Index: src/GenPoly/PolyMutator.cc
===================================================================
--- src/GenPoly/PolyMutator.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/PolyMutator.cc	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -23,9 +23,5 @@
 
 namespace GenPoly {
-	namespace {
-		const std::list<Label> noLabels;
-	}
-
-	PolyMutator::PolyMutator() : scopeTyVars( (TypeDecl::Kind)-1 ), env( 0 ) {}
+	PolyMutator::PolyMutator() : scopeTyVars( TypeDecl::Data{} ), env( 0 ) {}
 
 	void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) {
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision d9fa60af0bc172d6842f414cb608e0615d3582a5)
+++ src/GenPoly/ScrubTyVars.cc	(revision f7e749fe66afec27c3d97b647b99b4aaab0e6641)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ScrubTyVars.cc -- 
+// ScrubTyVars.cc --
 //
 // Author           : Richard C. Bilson
@@ -28,5 +28,5 @@
 		TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
 		if ( tyVar != tyVars.end() ) {
-			switch ( tyVar->second ) {
+			switch ( tyVar->second.kind ) {
 			  case TypeDecl::Any:
 			  case TypeDecl::Dtype:
@@ -52,5 +52,5 @@
 		return ty;
 	}
-	
+
 	Type * ScrubTyVars::mutate( StructInstType *structInst ) {
 		return mutateAggregateType( structInst );
