Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision bf050c5a1830779ff121a3d92926b2a9886e5d8f)
+++ src/Parser/DeclarationNode.cc	(revision 67467a31bf2574b870213fc394db73de3327ce27)
@@ -189,12 +189,7 @@
 
 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
-	DeclarationNode * newnode = new DeclarationNode;
-	newnode->type = new TypeData( TypeData::Enum );
-	newnode->type->enumeration.anon = name == nullptr;
-	newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
-	newnode->type->enumeration.constants = constants;
-	newnode->type->enumeration.body = body;
-	newnode->type->enumeration.typed = typed;
-	newnode->type->enumeration.hiding = hiding;
+	DeclarationNode * newnode = newAggregate( ast::AggregateDecl::Enum, name, nullptr, constants, body );
+	newnode->type->aggregate.typed = typed;
+	newnode->type->aggregate.hiding = hiding;
 	if ( base ) {
 		assert( typed );
@@ -549,4 +544,6 @@
 	newaggr->aggregate.body = false;
 	newaggr->aggregate.anon = oldaggr->aggregate.anon;
+	newaggr->aggregate.typed = oldaggr->aggregate.typed;
+	newaggr->aggregate.hiding = oldaggr->aggregate.hiding;
 	swap( newaggr, oldaggr );
 
@@ -558,37 +555,4 @@
 
 	moveUnionAttribute( olddecl, newdecl );
-
-	return newdecl;
-}
-
-// Helper for addTypedef, handles the case where the typedef wraps an
-// enumeration declaration (not a type), returns a chain of nodes.
-static DeclarationNode * addTypedefEnum(
-		DeclarationNode * olddecl, TypeData * newtype ) {
-	TypeData *& oldenum = olddecl->type->aggInst.aggregate;
-
-	// Handle anonymous enumeration: typedef enum { A, B, C } foo
-	// Give the typedefed type a consistent name across translation units.
-	if ( oldenum->enumeration.anon ) {
-		delete oldenum->enumeration.name;
-		oldenum->enumeration.name = new string( "__anonymous_" + *olddecl->name );
-		oldenum->enumeration.anon = false;
-		oldenum->qualifiers.reset();
-	}
-
-	// Replace the wrapped TypeData with a forward declaration.
-	TypeData * newenum = new TypeData( TypeData::Enum );
-	newenum->enumeration.name = oldenum->enumeration.name ? new string( *oldenum->enumeration.name ) : nullptr;
-	newenum->enumeration.body = false;
-	newenum->enumeration.anon = oldenum->enumeration.anon;
-	newenum->enumeration.typed = oldenum->enumeration.typed;
-	newenum->enumeration.hiding = oldenum->enumeration.hiding;
-	swap( newenum, oldenum );
-
-	newtype->base = olddecl->type;
-	olddecl->type = newtype;
-	DeclarationNode * newdecl = new DeclarationNode;
-	newdecl->type = newenum;
-	newdecl->next = olddecl;
 
 	return newdecl;
@@ -610,9 +574,4 @@
 			&& type->aggInst.aggregate->aggregate.body ) {
 		return addTypedefAggr( this, newtype );
-	// If this typedef is wrapping an enumeration, separate them out.
-	} else if ( TypeData::AggregateInst == type->kind
-			&& TypeData::Enum == type->aggInst.aggregate->kind
-			&& type->aggInst.aggregate->enumeration.body ) {
-		return addTypedefEnum( this, newtype );
 	// There is no internal declaration, just a type.
 	} else {
@@ -854,7 +813,4 @@
 						// typedef struct { int A } B is the only case?
 						extracted_named = ! extr->type->aggregate.anon;
-					} else if ( extr->type->kind == TypeData::Enum ) {
-						// typedef enum { A } B is the only case?
-						extracted_named = ! extr->type->enumeration.anon;
 					} else {
 						extracted_named = true;
@@ -1063,5 +1019,4 @@
 
 	switch ( type->kind ) {
-	case TypeData::Enum:
 	case TypeData::Aggregate: {
 		ast::BaseInstType * ret =
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision bf050c5a1830779ff121a3d92926b2a9886e5d8f)
+++ src/Parser/TypeData.cc	(revision 67467a31bf2574b870213fc394db73de3327ce27)
@@ -75,10 +75,4 @@
 		function.withExprs = nullptr;
 		break;
-	case Enum:
-		enumeration.name = nullptr;
-		enumeration.constants = nullptr;
-		enumeration.body = false;
-		enumeration.anon = false;
-		break;
 	case Aggregate:
 		aggregate.kind = ast::AggregateDecl::NoAggregate;
@@ -89,4 +83,6 @@
 		aggregate.body = false;
 		aggregate.anon = false;
+		aggregate.typed = false;
+		aggregate.hiding = EnumHiding::Visible;
 		break;
 	case AggregateInst:
@@ -153,8 +149,4 @@
 		delete aggInst.aggregate;
 		delete aggInst.params;
-		break;
-	case Enum:
-		delete enumeration.name;
-		delete enumeration.constants;
 		break;
 	case Symbolic:
@@ -231,10 +223,4 @@
 		newtype->aggInst.hoistType = aggInst.hoistType;
 		break;
-	case Enum:
-		newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
-		newtype->enumeration.constants = maybeCopy( enumeration.constants );
-		newtype->enumeration.body = enumeration.body;
-		newtype->enumeration.anon = enumeration.anon;
-		break;
 	case Symbolic:
 	case SymbolicInst:
@@ -375,18 +361,4 @@
 			os << string( indent + 2, ' ' ) << "with parameters" << endl;
 			aggInst.params->printList( os, indent + 2 );
-		} // if
-		break;
-	case Enum:
-		os << "enumeration " << *enumeration.name << endl;;
-		if ( enumeration.constants ) {
-			os << "with constants" << endl;
-			enumeration.constants->printList( os, indent + 2 );
-		} // if
-		if ( enumeration.body ) {
-			os << string( indent + 2, ' ' ) << "with body" << endl;
-		} // if
-		if ( base ) {
-			os << "for ";
-			base->print( os, indent + 2 );
 		} // if
 		break;
@@ -483,6 +455,4 @@
 	case Aggregate:
 		return aggregate.name;
-	case Enum:
-		return enumeration.name;
 	case Symbolic:
 	case SymbolicInst:
@@ -673,5 +643,4 @@
 		switch ( src->kind ) {
 		case TypeData::Aggregate:
-		case TypeData::Enum:
 			dst->base = new TypeData( TypeData::AggregateInst );
 			dst->base->aggInst.aggregate = src;
@@ -701,15 +670,11 @@
 		return rtype;
 	} else {
-		if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) {
+		if ( ltype->kind == TypeData::Aggregate ) {
 			// Hide type information aggregate instances.
 			rtype = new TypeData( TypeData::AggregateInst );
 			rtype->aggInst.aggregate = ltype;
 			rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership
-			if ( ltype->kind == TypeData::Aggregate ) {
-				rtype->aggInst.hoistType = ltype->aggregate.body;
-				rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
-			} else {
-				rtype->aggInst.hoistType = ltype->enumeration.body;
-			} // if
+			rtype->aggInst.hoistType = ltype->aggregate.body;
+			rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals );
 			rtype->qualifiers |= ltype->qualifiers;
 		} else {
@@ -730,14 +695,8 @@
 	if ( newType->kind == TypeData::AggregateInst ) {
 		// don't duplicate members
-		if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
-			delete newType->aggInst.aggregate->enumeration.constants;
-			newType->aggInst.aggregate->enumeration.constants = nullptr;
-			newType->aggInst.aggregate->enumeration.body = false;
-		} else {
-			assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
-			delete newType->aggInst.aggregate->aggregate.fields;
-			newType->aggInst.aggregate->aggregate.fields = nullptr;
-			newType->aggInst.aggregate->aggregate.body = false;
-		} // if
+		assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
+		delete newType->aggInst.aggregate->aggregate.fields;
+		newType->aggInst.aggregate->aggregate.fields = nullptr;
+		newType->aggInst.aggregate->aggregate.body = false;
 		// don't hoist twice
 		newType->aggInst.hoistType = false;
@@ -755,6 +714,5 @@
 TypeData * makeNewBase( TypeData * type ) {
 	switch ( type->kind ) {
-	case TypeData::Aggregate:
-	case TypeData::Enum: {
+	case TypeData::Aggregate: {
 		TypeData * out = new TypeData( TypeData::AggregateInst );
 		out->aggInst.aggregate = type;
@@ -1123,5 +1081,4 @@
 		);
 	case TypeData::Symbolic:
-	case TypeData::Enum:
 	case TypeData::Aggregate:
 		assert( false );
@@ -1138,9 +1095,4 @@
 	case TypeData::Aggregate:
 		if ( ! toplevel && td->aggregate.body ) {
-			ret = td->clone();
-		} // if
-		break;
-	case TypeData::Enum:
-		if ( ! toplevel && td->enumeration.body ) {
 			ret = td->clone();
 		} // if
@@ -1345,4 +1297,6 @@
 		buildForall( td->aggregate.params, at->params );
 		break;
+	case ast::AggregateDecl::Enum:
+		return buildEnum( td, std::move( attributes ), linkage );
 	case ast::AggregateDecl::Trait:
 		at = new ast::TraitDecl( td->location,
@@ -1369,19 +1323,4 @@
 		ast::Linkage::Spec linkage ) {
 	switch ( td->kind ) {
-	case TypeData::Enum:
-		if ( td->enumeration.body ) {
-			ast::EnumDecl * typedecl =
-				buildEnum( td, std::move( attributes ), linkage );
-			return new ast::EnumInstType(
-				typedecl,
-				buildQualifiers( td )
-			);
-		} else {
-			return new ast::EnumInstType(
-				*td->enumeration.name,
-				buildQualifiers( td )
-			);
-		} // if
-		break;
 	case TypeData::Aggregate:
 		if ( td->aggregate.body ) {
@@ -1400,4 +1339,9 @@
 				return new ast::UnionInstType(
 					strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
+					buildQualifiers( td )
+				);
+			case ast::AggregateDecl::Enum:
+				return new ast::EnumInstType(
+					strict_dynamic_cast<ast::EnumDecl *>( typedecl ),
 					buildQualifiers( td )
 				);
@@ -1423,4 +1367,9 @@
 					buildQualifiers( td )
 				);
+			case ast::AggregateDecl::Enum:
+				return new ast::EnumInstType(
+					*td->aggregate.name,
+					buildQualifiers( td )
+				);
 			case ast::AggregateDecl::Trait:
 				return new ast::TraitInstType(
@@ -1447,9 +1396,4 @@
 	TypeData * type = td->aggInst.aggregate;
 	switch ( type->kind ) {
-	case TypeData::Enum:
-		return new ast::EnumInstType(
-			*type->enumeration.name,
-			buildQualifiers( type )
-		);
 	case TypeData::Aggregate:
 		switch ( type->aggregate.kind ) {
@@ -1465,4 +1409,10 @@
 		case ast::AggregateDecl::Union:
 			ret = new ast::UnionInstType(
+				*type->aggregate.name,
+				buildQualifiers( type )
+			);
+			break;
+		case ast::AggregateDecl::Enum:
+			ret = new ast::EnumInstType(
 				*type->aggregate.name,
 				buildQualifiers( type )
@@ -1526,18 +1476,19 @@
 		std::vector<ast::ptr<ast::Attribute>> && attributes,
 		ast::Linkage::Spec linkage ) {
-	assert( td->kind == TypeData::Enum );
+	assert( td->kind == TypeData::Aggregate );
+	assert( td->aggregate.kind == ast::AggregateDecl::Enum );
 	ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
 	ast::EnumDecl * ret = new ast::EnumDecl(
 		td->location,
-		*td->enumeration.name,
-		td->enumeration.typed,
+		*td->aggregate.name,
+		td->aggregate.typed,
 		std::move( attributes ),
 		linkage,
 		baseType
 	);
-	buildList( td->enumeration.constants, ret->members );
+	buildList( td->aggregate.fields, ret->members );
 	auto members = ret->members.begin();
-	ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
-	for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = cur->next, ++members ) {
+	ret->hide = td->aggregate.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
+	for ( const DeclarationNode * cur = td->aggregate.fields ; cur != nullptr ; cur = cur->next, ++members ) {
 		if ( cur->enumInLine ) {
 			// Do Nothing
@@ -1560,5 +1511,5 @@
 		// if
 	} // for
-	ret->body = td->enumeration.body;
+	ret->body = td->aggregate.body;
 	return ret;
 } // buildEnum
@@ -1704,6 +1655,4 @@
 	} else if ( td->kind == TypeData::Aggregate ) {
 		return buildAggregate( td, std::move( attributes ), linkage );
-	} else if ( td->kind == TypeData::Enum ) {
-		return buildEnum( td, std::move( attributes ), linkage );
 	} else if ( td->kind == TypeData::Symbolic ) {
 		return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision bf050c5a1830779ff121a3d92926b2a9886e5d8f)
+++ src/Parser/TypeData.h	(revision 67467a31bf2574b870213fc394db73de3327ce27)
@@ -42,5 +42,5 @@
 	static const char * builtinTypeNames[];
 
-	enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
+	enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, EnumConstant, Symbolic,
 				SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
 
@@ -48,10 +48,18 @@
 		ast::AggregateDecl::Aggregate kind;
 		const std::string * name = nullptr;
+		// Polymorphics parameters. (Polymorphic types only.)
 		DeclarationNode * params = nullptr;
-		ExpressionNode * actuals = nullptr;				// holds actual parameters later applied to AggInst
+		// Arguments later applied to AggInst. (Polymorphic types only.)
+		ExpressionNode * actuals = nullptr;
+		// Only set if body is true. (Constants for enumerations.)
 		DeclarationNode * fields = nullptr;
 		std::vector<ast::ptr<ast::Attribute>> attributes;
+		// Is this a declaration with a body (may have fields)?
 		bool body;
+		// Is this type anonymous? (Name can still be set to generated name.)
 		bool anon;
+		// Is this a typed enumeration? Type may be stored in base.
+		bool typed;
+		EnumHiding hiding;
 	};
 
@@ -66,13 +74,4 @@
 		bool isVarLen;
 		bool isStatic;
-	};
-
-	struct Enumeration_t {
-		const std::string * name = nullptr;
-		DeclarationNode * constants = nullptr;
-		bool body;
-		bool anon;
-		bool typed;
-		EnumHiding hiding;
 	};
 
@@ -114,5 +113,4 @@
 	AggInst_t aggInst;
 	Array_t array;
-	Enumeration_t enumeration;
 	Function_t function;
 	Symbolic_t symbolic;
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision bf050c5a1830779ff121a3d92926b2a9886e5d8f)
+++ src/Parser/parser.yy	(revision 67467a31bf2574b870213fc394db73de3327ce27)
@@ -202,6 +202,6 @@
 
 DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) {
-	if ( ! fieldList ) {								// field declarator ?
-		if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) {
+	if ( nullptr == fieldList ) {
+		if ( !( typeSpec->type && typeSpec->type->kind == TypeData::Aggregate ) ) {
 			stringstream ss;
 			// printf( "fieldDecl1 typeSpec %p\n", typeSpec ); typeSpec->type->print( std::cout );
@@ -2173,5 +2173,5 @@
 		{
 			SemanticError( yylloc, "syntax error, expecting ';' at end of \"%s\" declaration.",
-						   $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ) );
+						   ast::AggregateDecl::aggrString( $1->type->aggregate.kind ) );
 			$$ = nullptr;
 		}
@@ -3245,8 +3245,6 @@
 			if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static &&
 				 $1->type && $1->type->kind == TypeData::AggregateInst ) {
-				if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
-					SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
-				} else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
-					SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
+				if ( $1->type->aggInst.aggregate->aggregate.anon ) {
+					SemanticError( yylloc, "extern anonymous aggregate is currently unimplemented." ); $$ = nullptr;
 				}
 			}
