Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/AST/Convert.cpp	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Thu May 09 15::37::05 2019
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jul 25 22:21:46 2019
-// Update Count     : 13
+// Last Modified On : Tue Dec 10 22:20:10 2019
+// Update Count     : 32
 //
 
@@ -245,5 +245,5 @@
 		auto decl = new StructDecl(
 			node->name,
-			node->kind,
+			(AggregateDecl::Aggregate)node->kind,
 			get<Attribute>().acceptL( node->attributes ),
 			LinkageSpec::Spec( node->linkage.val )
@@ -675,19 +675,6 @@
 
 	const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
-		KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
-		switch (node->target) {
-			case ast::KeywordCastExpr::Coroutine:
-				castTarget = KeywordCastExpr::Coroutine;
-				break;
-			case ast::KeywordCastExpr::Thread:
-				castTarget = KeywordCastExpr::Thread;
-				break;
-			case ast::KeywordCastExpr::Monitor:
-				castTarget = KeywordCastExpr::Monitor;
-				break;
-			default:
-				break;
-		}
-		assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
+		AggregateDecl::Aggregate castTarget = (AggregateDecl::Aggregate)node->target;
+		assert( AggregateDecl::Generator <= castTarget && castTarget <= AggregateDecl::Thread );
 		auto expr = visitBaseExpr( node,
 			new KeywordCastExpr(
@@ -1504,5 +1491,5 @@
 			old->location,
 			old->name,
-			old->kind,
+			(ast::AggregateDecl::Aggregate)old->kind,
 			GET_ACCEPT_V(attributes, Attribute),
 			{ old->linkage.val }
@@ -2045,20 +2032,7 @@
 	}
 
-	virtual void visit( const KeywordCastExpr * old) override final {
-		ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
-		switch (old->target) {
-			case KeywordCastExpr::Coroutine:
-				castTarget = ast::KeywordCastExpr::Coroutine;
-				break;
-			case KeywordCastExpr::Thread:
-				castTarget = ast::KeywordCastExpr::Thread;
-				break;
-			case KeywordCastExpr::Monitor:
-				castTarget = ast::KeywordCastExpr::Monitor;
-				break;
-			default:
-				break;
-		}
-		assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
+	virtual void visit( const KeywordCastExpr * old ) override final {
+		ast::AggregateDecl::Aggregate castTarget = (ast::AggregateDecl::Aggregate)old->target;
+		assert( ast::AggregateDecl::Generator <= castTarget && castTarget <= ast::AggregateDecl::Thread );
 		this->node = visitBaseExpr( old,
 			new ast::KeywordCastExpr(
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/AST/Decl.cpp	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Thu May 9 10:00:00 2019
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 16:41:39 2019
+// Update Count     : 18
 //
 
@@ -18,5 +18,4 @@
 #include <cassert>             // for assert, strict_dynamic_cast
 #include <iostream>
-#include <string>
 #include <unordered_map>
 
@@ -56,14 +55,14 @@
 // --- TypeDecl
 
-std::string TypeDecl::typeString() const {
-	static const std::string kindNames[] = { "object type", "function type", "tuple type" };
+const char * TypeDecl::typeString() const {
+	static const char * kindNames[] = { "sized object type", "sized function type", "sized tuple type" };
 	assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1,
 		"typeString: kindNames is out of sync." );
 	assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
-	return (sized ? "sized " : "") + kindNames[ kind ];
+	return sized ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ]; // sizeof includes '\0'
 }
 
-std::string TypeDecl::genTypeString() const {
-	static const std::string kindNames[] = { "dtype", "ftype", "ttype" };
+const char * TypeDecl::genTypeString() const {
+	static const char * kindNames[] = { "dtype", "ftype", "ttype" };
 	assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "genTypeString: kindNames is out of sync." );
 	assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
@@ -73,4 +72,13 @@
 std::ostream & operator<< ( std::ostream & out, const TypeDecl::Data & data ) {
 	return out << data.kind << ", " << data.isComplete;
+}
+
+// --- AggregateDecl
+
+// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
+static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
+
+const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
+	return aggregateNames[aggr];
 }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/AST/Decl.hpp	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Thu May 9 10:00:00 2019
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 08:20:20 2019
+// Update Count     : 16
 //
 
@@ -154,5 +154,5 @@
 
 	/// Produces a name for the kind of alias
-	virtual std::string typeString() const = 0;
+	virtual const char * typeString() const = 0;
 
 private:
@@ -190,7 +190,7 @@
 	  init( i ) {}
 
-	std::string typeString() const override;
+	const char * typeString() const override;
 	/// Produces a name for generated code
-	std::string genTypeString() const;
+	const char * genTypeString() const;
 
 	/// convenience accessor to match Type::isComplete()
@@ -212,5 +212,5 @@
 	: NamedTypeDecl( loc, name, storage, b, spec ) {}
 
-	std::string typeString() const override { return "typedef"; }
+	const char * typeString() const override { return "typedef"; }
 
 	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
@@ -223,4 +223,7 @@
 class AggregateDecl : public Decl {
 public:
+	enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
+	static const char * aggrString( Aggregate aggr );
+
 	std::vector<ptr<Decl>> members;
 	std::vector<ptr<TypeDecl>> params;
@@ -237,5 +240,5 @@
 
 	/// Produces a name for the kind of aggregate
-	virtual std::string typeString() const = 0;
+	virtual const char * typeString() const = 0;
 
 private:
@@ -247,18 +250,18 @@
 class StructDecl final : public AggregateDecl {
 public:
-	DeclarationNode::Aggregate kind;
+	Aggregate kind;
 
 	StructDecl( const CodeLocation& loc, const std::string& name,
-		DeclarationNode::Aggregate kind = DeclarationNode::Struct,
+		Aggregate kind = Struct,
 		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
 	: AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
 
-	bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
-	bool is_monitor() { return kind == DeclarationNode::Monitor; }
-	bool is_thread() { return kind == DeclarationNode::Thread; }
-
-	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
-
-	std::string typeString() const override { return "struct"; }
+	bool is_coroutine() { return kind == Coroutine; }
+	bool is_monitor() { return kind == Monitor; }
+	bool is_thread() { return kind == Thread; }
+
+	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
+
+	const char * typeString() const override { return aggrString( kind ); }
 
 private:
@@ -276,5 +279,5 @@
 	const Decl * accept( Visitor& v ) const override { return v.visit( this ); }
 
-	std::string typeString() const override { return "union"; }
+	const char * typeString() const override { return aggrString( Union ); }
 
 private:
@@ -295,5 +298,5 @@
 	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
 
-	std::string typeString() const override { return "enum"; }
+	const char * typeString() const override { return aggrString( Enum ); }
 
 private:
@@ -314,5 +317,5 @@
 	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
 
-	std::string typeString() const override { return "trait"; }
+	const char * typeString() const override { return "trait"; }
 
 private:
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/AST/Expr.cpp	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Wed May 15 17:00:00 2019
-// Last Modified By : Andrew Beach
+// Last Modified By : Peter A. Buhr
 // Created On       : Thr Jun 13 13:38:00 2019
-// Update Count     : 2
+// Update Count     : 6
 //
 
@@ -141,13 +141,6 @@
 // --- KeywordCastExpr
 
-const std::string & KeywordCastExpr::targetString() const {
-	static const std::string targetStrs[] = {
-		"coroutine", "thread", "monitor"
-	};
-	static_assert(
-		(sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
-		"Each KeywordCastExpr::Target should have a corresponding string representation"
-	);
-	return targetStrs[(unsigned long)target];
+const char * KeywordCastExpr::targetString() const {
+	return AggregateDecl::aggrString( target );
 }
 
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/AST/Expr.hpp	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Fri May 10 10:30:00 2019
-// Last Modified By : Aaron B. Moss
+// Last Modified By : Peter A. Buhr
 // Created On       : Fri May 10 10:30:00 2019
-// Update Count     : 1
+// Update Count     : 7
 //
 
@@ -26,4 +26,5 @@
 #include "Fwd.hpp"        // for UniqueId
 #include "Label.hpp"
+#include "Decl.hpp"
 #include "ParseNode.hpp"
 #include "Visitor.hpp"
@@ -300,11 +301,11 @@
 public:
 	ptr<Expr> arg;
-	enum Target { Coroutine, Thread, Monitor, NUMBER_OF_TARGETS } target;
-
-	KeywordCastExpr( const CodeLocation & loc, const Expr * a, Target t )
+	ast::AggregateDecl::Aggregate target;
+
+	KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t )
 	: Expr( loc ), arg( a ), target( t ) {}
 
 	/// Get a name for the target type
-	const std::string& targetString() const;
+	const char * targetString() const;
 
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Concurrency/Keywords.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -11,5 +11,5 @@
 // Last Modified By :
 // Last Modified On :
-// Update Count     : 5
+// Update Count     : 9
 //
 
@@ -53,5 +53,5 @@
 	  public:
 
-	  	ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, KeywordCastExpr::Target cast_target ) :
+	  	ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate cast_target ) :
 		  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
 
@@ -76,5 +76,5 @@
 		const std::string context_error;
 		bool needs_main;
-		KeywordCastExpr::Target cast_target;
+		AggregateDecl::Aggregate cast_target;
 
 		StructDecl   * type_decl = nullptr;
@@ -101,5 +101,5 @@
 			"thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
 			true,
-			KeywordCastExpr::Thread
+			AggregateDecl::Thread
 		)
 		{}
@@ -133,5 +133,5 @@
 			"coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
 			true,
-			KeywordCastExpr::Coroutine
+			AggregateDecl::Coroutine
 		)
 		{}
@@ -165,5 +165,5 @@
 			"monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
 			false,
-			KeywordCastExpr::Monitor
+			AggregateDecl::Monitor
 		)
 		{}
Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Concurrency/Waitfor.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -11,5 +11,5 @@
 // Last Modified By :
 // Last Modified On :
-// Update Count     : 7
+// Update Count     : 10
 //
 
@@ -23,4 +23,5 @@
 #include "Common/PassVisitor.h"    // for PassVisitor
 #include "Common/SemanticError.h"  // for SemanticError
+#include "Common/UniqueName.h"	   // for UniqueName
 #include "Common/utility.h"        // for deleteAll, map_range
 #include "CodeGen/OperatorTable.h" // for isConstructor
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/DeclarationNode.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jul 25 22:17:10 2019
-// Update Count     : 1116
+// Last Modified On : Wed Dec 11 07:40:14 2019
+// Update Count     : 1123
 //
 
@@ -47,5 +47,4 @@
 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
-const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" };
 const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" };
 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
@@ -267,5 +266,5 @@
 }
 
-DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
+DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Aggregate );
@@ -328,5 +327,5 @@
 	newnode->type = new TypeData( TypeData::Aggregate );
 	newnode->type->aggregate.name = name;
-	newnode->type->aggregate.kind = Trait;
+	newnode->type->aggregate.kind = AggregateDecl::Trait;
 	newnode->type->aggregate.params = params;
 	newnode->type->aggregate.fields = asserts;
@@ -338,5 +337,5 @@
 	newnode->type = new TypeData( TypeData::AggregateInst );
 	newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
-	newnode->type->aggInst.aggregate->aggregate.kind = Trait;
+	newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
 	newnode->type->aggInst.aggregate->aggregate.name = name;
 	newnode->type->aggInst.params = params;
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/ExpressionNode.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Aug  4 20:57:55 2019
-// Update Count     : 978
+// Last Modified On : Tue Dec 10 23:01:47 2019
+// Update Count     : 980
 //
 
@@ -434,5 +434,5 @@
 } // build_cast
 
-Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node ) {
+Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) {
 	return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
 }
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/ParseNode.h	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jul 25 22:17:10 2019
-// Update Count     : 876
+// Last Modified On : Wed Dec 11 07:40:07 2019
+// Update Count     : 882
 //
 
@@ -29,4 +29,5 @@
 #include "Common/utility.h"        // for maybeClone, maybeBuild
 #include "Parser/LinkageSpec.h"    // for Spec
+#include "SynTree/Declaration.h"   // for Aggregate
 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
 #include "SynTree/Label.h"         // for Label
@@ -184,5 +185,5 @@
 
 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
-Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
+Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
@@ -217,6 +218,4 @@
 	enum Length { Short, Long, LongLong, NoLength };
 	static const char * lengthNames[];
-	enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
-	static const char * aggregateNames[];
 	enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
 	static const char * typeClassNames[];
@@ -237,5 +236,5 @@
 	static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
 	static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
-	static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
+	static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
 	static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
 	static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/TypeData.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:12:51 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 13 18:16:23 2019
-// Update Count     : 649
+// Last Modified On : Wed Dec 11 07:48:33 2019
+// Update Count     : 659
 //
 
@@ -67,5 +67,5 @@
 	  case Aggregate:
 		// aggregate = new Aggregate_t;
-		aggregate.kind = DeclarationNode::NoAggregate;
+		aggregate.kind = AggregateDecl::NoAggregate;
 		aggregate.name = nullptr;
 		aggregate.params = nullptr;
@@ -345,5 +345,5 @@
 		break;
 	  case Aggregate:
-		os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
+		os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
 		if ( aggregate.params ) {
 			os << string( indent + 2, ' ' ) << "with type parameters" << endl;
@@ -768,16 +768,16 @@
 	AggregateDecl * at;
 	switch ( td->aggregate.kind ) {
-	  case DeclarationNode::Struct:
-	  case DeclarationNode::Coroutine:
-	  case DeclarationNode::Monitor:
-	  case DeclarationNode::Thread:
+	  case AggregateDecl::Struct:
+	  case AggregateDecl::Coroutine:
+	  case AggregateDecl::Monitor:
+	  case AggregateDecl::Thread:
 		at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
 		buildForall( td->aggregate.params, at->get_parameters() );
 		break;
-	  case DeclarationNode::Union:
+	  case AggregateDecl::Union:
 		at = new UnionDecl( *td->aggregate.name, attributes, linkage );
 		buildForall( td->aggregate.params, at->get_parameters() );
 		break;
-	  case DeclarationNode::Trait:
+	  case AggregateDecl::Trait:
 		at = new TraitDecl( *td->aggregate.name, attributes, linkage );
 		buildList( td->aggregate.params, at->get_parameters() );
@@ -809,14 +809,14 @@
 			  AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
 			  switch ( type->aggregate.kind ) {
-				case DeclarationNode::Struct:
-				case DeclarationNode::Coroutine:
-				case DeclarationNode::Monitor:
-				case DeclarationNode::Thread:
+				case AggregateDecl::Struct:
+				case AggregateDecl::Coroutine:
+				case AggregateDecl::Monitor:
+				case AggregateDecl::Thread:
 				  ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
 				  break;
-				case DeclarationNode::Union:
+				case AggregateDecl::Union:
 				  ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
 				  break;
-				case DeclarationNode::Trait:
+				case AggregateDecl::Trait:
 				  assert( false );
 				  //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
@@ -827,14 +827,14 @@
 		  } else {
 			  switch ( type->aggregate.kind ) {
-				case DeclarationNode::Struct:
-				case DeclarationNode::Coroutine:
-				case DeclarationNode::Monitor:
-				case DeclarationNode::Thread:
+				case AggregateDecl::Struct:
+				case AggregateDecl::Coroutine:
+				case AggregateDecl::Monitor:
+				case AggregateDecl::Thread:
 				  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
 				  break;
-				case DeclarationNode::Union:
+				case AggregateDecl::Union:
 				  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
 				  break;
-				case DeclarationNode::Trait:
+				case AggregateDecl::Trait:
 				  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
 				  break;
@@ -863,14 +863,14 @@
 	  case TypeData::Aggregate: {
 		  switch ( type->aggregate.kind ) {
-			case DeclarationNode::Struct:
-			case DeclarationNode::Coroutine:
-			case DeclarationNode::Monitor:
-			case DeclarationNode::Thread:
+			case AggregateDecl::Struct:
+			case AggregateDecl::Coroutine:
+			case AggregateDecl::Monitor:
+			case AggregateDecl::Thread:
 			  ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
 			  break;
-			case DeclarationNode::Union:
+			case AggregateDecl::Union:
 			  ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
 			  break;
-			case DeclarationNode::Trait:
+			case AggregateDecl::Trait:
 			  ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
 			  break;
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/TypeData.h	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:18:36 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Nov  1 20:56:46 2018
-// Update Count     : 196
+// Last Modified On : Tue Dec 10 23:01:07 2019
+// Update Count     : 198
 //
 
@@ -30,5 +30,5 @@
 
 	struct Aggregate_t {
-		DeclarationNode::Aggregate kind;
+		AggregateDecl::Aggregate kind;
 		const std::string * name = nullptr;
 		DeclarationNode * params = nullptr;
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/Parser/parser.yy	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Dec  7 10:43:44 2019
-// Update Count     : 4394
+// Last Modified On : Tue Dec 10 23:07:17 2019
+// Update Count     : 4400
 //
 
@@ -51,4 +51,5 @@
 using namespace std;
 
+#include "SynTree/Declaration.h"
 #include "ParseNode.h"
 #include "TypedefTable.h"
@@ -211,16 +212,4 @@
 } // forCtrl
 
-KeywordCastExpr::Target Aggregate2Target( DeclarationNode::Aggregate aggr ) {
-	KeywordCastExpr::Target target;
-	switch ( aggr ) {
-	  case DeclarationNode::Coroutine: target = KeywordCastExpr::Coroutine; break;
-	  case DeclarationNode::Monitor: target = KeywordCastExpr::Monitor; break;
-	  case DeclarationNode::Thread: target = KeywordCastExpr::Thread; break;
-	  default: abort();
-	} // switch
-	return target;
-} // Aggregate2Target
-
-
 bool forall = false, yyy = false;						// aggregate have one or more forall qualifiers ?
 
@@ -248,5 +237,5 @@
 	ExpressionNode * en;
 	DeclarationNode * decl;
-	DeclarationNode::Aggregate aggKey;
+	AggregateDecl::Aggregate aggKey;
 	DeclarationNode::TypeClass tclass;
 	StatementNode * sn;
@@ -662,5 +651,5 @@
 		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
 	| postfix_expression '.' aggregate_control
-		{ $$ = new ExpressionNode( build_keyword_cast( Aggregate2Target( $3 ), $1 ) ); }
+		{ $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
 	| postfix_expression ARROW identifier
 		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
@@ -807,5 +796,5 @@
 		{ $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
 	| '(' aggregate_control '&' ')' cast_expression		// CFA
-		{ $$ = new ExpressionNode( build_keyword_cast( Aggregate2Target( $2 ), $5 ) ); }
+		{ $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
 		// VIRTUAL cannot be opt because of look ahead issues
 	| '(' VIRTUAL ')' cast_expression					// CFA
@@ -2071,20 +2060,20 @@
 aggregate_data:
 	STRUCT
-		{ yyy = true; $$ = DeclarationNode::Struct; }
+		{ yyy = true; $$ = AggregateDecl::Struct; }
 	| UNION
-		{ yyy = true; $$ = DeclarationNode::Union; }
+		{ yyy = true; $$ = AggregateDecl::Union; }
 	| EXCEPTION											// CFA
-		{ yyy = true; $$ = DeclarationNode::Exception; }
+		{ yyy = true; $$ = AggregateDecl::Exception; }
 	;
 
 aggregate_control:										// CFA
 	GENERATOR
-		{ yyy = true; $$ = DeclarationNode::Coroutine; }
+		{ yyy = true; $$ = AggregateDecl::Coroutine; }
 	| COROUTINE
-		{ yyy = true; $$ = DeclarationNode::Coroutine; }
+		{ yyy = true; $$ = AggregateDecl::Coroutine; }
 	| MONITOR
-		{ yyy = true; $$ = DeclarationNode::Monitor; }
+		{ yyy = true; $$ = AggregateDecl::Monitor; }
 	| THREAD
-		{ yyy = true; $$ = DeclarationNode::Thread; }
+		{ yyy = true; $$ = AggregateDecl::Thread; }
 	;
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SymTab/Validate.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:50:04 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  7 6:42:00 2019
-// Update Count     : 360
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 10 22:22:01 2019
+// Update Count     : 362
 //
 
@@ -1049,5 +1049,5 @@
 		Type * designatorType = tyDecl->base->stripDeclarator();
 		if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
-			declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
+			declsToAddBefore.push_back( new StructDecl( aggDecl->name, AggregateDecl::Struct, noAttributes, tyDecl->linkage ) );
 		} else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
 			declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
Index: src/SynTree/AggregateDecl.cc
===================================================================
--- src/SynTree/AggregateDecl.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/AggregateDecl.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 23:56:39 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug  4 14:22:00 2017
-// Update Count     : 22
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 16:31:55 2019
+// Update Count     : 29
 //
 
@@ -21,7 +21,15 @@
 #include "Common/utility.h"      // for printAll, cloneAll, deleteAll
 #include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
+#include "Initializer.h"
 #include "Parser/LinkageSpec.h"  // for Spec, linkageName, Cforall
 #include "Type.h"                // for Type, Type::StorageClasses
 
+
+// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
+static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
+
+const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
+	return aggregateNames[aggr];
+}
 
 AggregateDecl::AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, Type::StorageClasses(), linkage ), body( false ), attributes( attributes ) {
@@ -78,11 +86,11 @@
 }
 
-std::string StructDecl::typeString() const { return "struct"; }
+const char * StructDecl::typeString() const { return aggrString( kind ); }
 
-std::string UnionDecl::typeString() const { return "union"; }
+const char * UnionDecl::typeString() const { return aggrString( Union ); }
 
-std::string EnumDecl::typeString() const { return "enum"; }
+const char * EnumDecl::typeString() const { return aggrString( Enum ); }
 
-std::string TraitDecl::typeString() const { return "trait"; }
+const char * TraitDecl::typeString() const { return aggrString( Trait ); }
 
 bool EnumDecl::valueOf( Declaration * enumerator, long long int & value ) {
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/Declaration.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  9 14:38:00 2017
-// Update Count     : 25
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 16:39:56 2019
+// Update Count     : 36
 //
 
@@ -24,6 +24,8 @@
 #include "SynTree/Statement.h"       // for AsmStmt
 #include "SynTree/SynTree.h"         // for UniqueId
+#include "SynTree/Expression.h"
 #include "Type.h"                    // for Type, Type::StorageClasses
 
+// To canonicalize declarations
 static UniqueId lastUniqueId = 0;
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/Declaration.h	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr May  2 10:47:00 2019
-// Update Count     : 135
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 16:48:20 2019
+// Update Count     : 149
 //
 
@@ -25,5 +25,4 @@
 #include "Mutator.h"             // for Mutator
 #include "Parser/LinkageSpec.h"  // for Spec, Cforall
-#include "Parser/ParseNode.h"    // for DeclarationNode, DeclarationNode::Ag...
 #include "SynTree.h"             // for UniqueId
 #include "SynTree/Type.h"        // for Type, Type::StorageClasses, Type::Fu...
@@ -194,5 +193,5 @@
 	std::list< DeclarationWithType* >& get_assertions() { return assertions; }
 
-	virtual std::string typeString() const = 0;
+	virtual const char * typeString() const = 0;
 
 	virtual NamedTypeDecl *clone() const override = 0;
@@ -237,6 +236,6 @@
 	TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
 
-	virtual std::string typeString() const override;
-	virtual std::string genTypeString() const;
+	virtual const char * typeString() const override;
+	virtual const char * genTypeString() const;
 
 	virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
@@ -257,5 +256,5 @@
 	TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
 
-	virtual std::string typeString() const override;
+	virtual const char * typeString() const override;
 
 	virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
@@ -269,4 +268,7 @@
 	typedef Declaration Parent;
   public:
+	enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
+	static const char * aggrString( Aggregate aggr );
+
 	std::list<Declaration*> members;
 	std::list<TypeDecl*> parameters;
@@ -291,5 +293,5 @@
 	virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
   protected:
-	virtual std::string typeString() const = 0;
+	virtual const char * typeString() const = 0;
 };
 
@@ -297,10 +299,10 @@
 	typedef AggregateDecl Parent;
   public:
-	StructDecl( const std::string &name, DeclarationNode::Aggregate kind = DeclarationNode::Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ) {}
+	StructDecl( const std::string &name, Aggregate kind = Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ) {}
 	StructDecl( const StructDecl &other ) : Parent( other ), kind( other.kind ) {}
 
-	bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
-	bool is_monitor() { return kind == DeclarationNode::Monitor; }
-	bool is_thread() { return kind == DeclarationNode::Thread; }
+	bool is_coroutine() { return kind == Coroutine; }
+	bool is_monitor() { return kind == Monitor; }
+	bool is_thread() { return kind == Thread; }
 
 	virtual StructDecl *clone() const override { return new StructDecl( *this ); }
@@ -308,7 +310,7 @@
 	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	DeclarationNode::Aggregate kind;
-  private:
-	virtual std::string typeString() const override;
+	Aggregate kind;
+  private:
+	virtual const char * typeString() const override;
 };
 
@@ -324,5 +326,5 @@
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
-	virtual std::string typeString() const override;
+	virtual const char * typeString() const override;
 };
 
@@ -341,5 +343,5 @@
   private:
 	std::unordered_map< std::string, long long int > enumValues;
-	virtual std::string typeString() const override;
+	virtual const char * typeString() const override;
 };
 
@@ -357,5 +359,5 @@
 	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
-	virtual std::string typeString() const override;
+	virtual const char * typeString() const override;
 };
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/Expression.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 15 13:43:00 2019
-// Update Count     : 64
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 07:55:15 2019
+// Update Count     : 70
 //
 
@@ -22,5 +22,4 @@
 
 #include "Common/utility.h"          // for maybeClone, cloneAll, deleteAll
-#include "Declaration.h"             // for ObjectDecl, DeclarationWithType
 #include "Expression.h"              // for Expression, ImplicitCopyCtorExpr
 #include "InitTweak/InitTweak.h"     // for getCallArg, getPointerBase
@@ -294,5 +293,5 @@
 }
 
-KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) {
+KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) {
 }
 
@@ -304,13 +303,6 @@
 }
 
-const std::string & KeywordCastExpr::targetString() const {
-	static const std::string targetStrs[] = {
-		"coroutine", "thread", "monitor"
-	};
-	static_assert(
-		(sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
-		"Each KeywordCastExpr::Target should have a corresponding string representation"
-	);
-	return targetStrs[(unsigned long)target];
+const char * KeywordCastExpr::targetString() const {
+	return AggregateDecl::aggrString( target );
 }
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/Expression.h	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 15 13:46:00 2019
-// Update Count     : 54
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 16:50:19 2019
+// Update Count     : 60
 //
 
@@ -28,4 +28,5 @@
 #include "Label.h"                // for Label
 #include "Mutator.h"              // for Mutator
+#include "Declaration.h"          // for Aggregate
 #include "SynTree.h"              // for UniqueId
 #include "Visitor.h"              // for Visitor
@@ -229,19 +230,16 @@
 public:
 	Expression * arg;
-	enum Target {
-		Coroutine, Thread, Monitor, NUMBER_OF_TARGETS
-	};
 	struct Concrete {
 		std::string field;
 		std::string getter;
 	};
-	Target target;
+	AggregateDecl::Aggregate target;
 	Concrete concrete_target;
 
-	KeywordCastExpr( Expression * arg, Target target );
+	KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target );
 	KeywordCastExpr( const KeywordCastExpr & other );
 	virtual ~KeywordCastExpr();
 
-	const std::string & targetString() const;
+	const char * targetString() const;
 
 	virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); }
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/FunctionDecl.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 16 08:33:41 2017
-// Update Count     : 74
+// Last Modified On : Sat Dec  7 17:40:09 2019
+// Update Count     : 75
 //
 
@@ -23,4 +23,5 @@
 #include "Common/utility.h"      // for maybeClone, printAll
 #include "Declaration.h"         // for FunctionDecl, FunctionDecl::Parent
+#include "Expression.h"
 #include "Parser/LinkageSpec.h"  // for Spec, linkageName, Cforall
 #include "Statement.h"           // for CompoundStmt
Index: src/SynTree/NamedTypeDecl.cc
===================================================================
--- src/SynTree/NamedTypeDecl.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/NamedTypeDecl.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  9 13:28:00 2017
-// Update Count     : 14
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 08:26:17 2019
+// Update Count     : 15
 //
 
@@ -78,5 +78,5 @@
 }
 
-std::string TypedefDecl::typeString() const { return "typedef"; }
+const char * TypedefDecl::typeString() const { return "typedef"; }
 
 // Local Variables: //
Index: src/SynTree/TypeDecl.cc
===================================================================
--- src/SynTree/TypeDecl.cc	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ src/SynTree/TypeDecl.cc	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  9 14:35:00 2017
-// Update Count     : 6
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Dec 11 17:56:30 2019
+// Update Count     : 10
 //
 
@@ -18,4 +18,5 @@
 
 #include "Common/utility.h"  // for maybeClone
+#include "Parser/ParseNode.h"
 #include "Declaration.h"     // for TypeDecl, TypeDecl::Data, TypeDecl::Kind...
 #include "Type.h"            // for Type, Type::StorageClasses
@@ -31,13 +32,13 @@
 }
 
-std::string TypeDecl::typeString() const {
-	static const std::string kindNames[] = { "object type", "function type", "tuple type" };
+const char * TypeDecl::typeString() const {
+	static const char * kindNames[] = { "sized object type", "sized function type", "sized tuple type" };
 	assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "typeString: kindNames is out of sync." );
 	assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
-	return (isComplete() ? "sized " : "") + kindNames[ kind ];
+	return isComplete() ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ]; // sizeof includes '\0'
 }
 
-std::string TypeDecl::genTypeString() const {
-	static const std::string kindNames[] = { "dtype", "ftype", "ttype" };
+const char * TypeDecl::genTypeString() const {
+	static const char * kindNames[] = { "dtype", "ftype", "ttype" };
 	assertf( sizeof(kindNames)/sizeof(kindNames[0]) == DeclarationNode::NoTypeClass-1, "genTypeString: kindNames is out of sync." );
 	assertf( kind < sizeof(kindNames)/sizeof(kindNames[0]), "TypeDecl's kind is out of bounds." );
Index: tests/concurrent/.expect/keywordErrors.txt
===================================================================
--- tests/concurrent/.expect/keywordErrors.txt	(revision 98d6965d977b39416143b988d932952fb731637a)
+++ tests/concurrent/.expect/keywordErrors.txt	(revision 312029a731fd1bf1cdd24d3e1d75abf51eb09d71)
@@ -1,6 +1,6 @@
 concurrent/keywordErrors.cfa:1:1 error: thread keyword requires threads to be in scope, add #include <thread.hfa>
-struct A: with body 1
+thread A: with body 1
 
 concurrent/keywordErrors.cfa:6:1 error: thread keyword requires threads to be in scope, add #include <thread.hfa>
-struct B: with body 1
+thread B: with body 1
 
