Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/AST/Decl.cpp	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Thu May 9 10:00:00 2019
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 13 16:23:15 2019
-// Update Count     : 20
+// Last Modified On : Mon Jan 11 20:53:23 2021
+// Update Count     : 21
 //
 
@@ -78,6 +78,6 @@
 
 const char * TypeDecl::typeString() const {
-	static const char * kindNames[] = { "sized data type", "sized object type", "sized function type", "sized tuple type" };
-	static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
+	static const char * kindNames[] = { "data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "array length type" };
+	static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
 	assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
 	return sized ? kindNames[ kind ] : &kindNames[ kind ][ sizeof("sized") ]; // sizeof includes '\0'
@@ -85,6 +85,6 @@
 
 const char * TypeDecl::genTypeString() const {
-	static const char * kindNames[] = { "dtype", "otype", "ftype", "ttype" };
-	static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
+	static const char * kindNames[] = { "T &", "T *", "T", "(*)", "T ...", "[T]" };
+	static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
 	assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
 	return kindNames[ kind ];
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/AST/Decl.hpp	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Thu May 9 10:00:00 2019
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 13 17:38:33 2019
-// Update Count     : 29
+// Last Modified On : Mon Jan 11 20:48:38 2021
+// Update Count     : 30
 //
 
@@ -175,5 +175,5 @@
 class TypeDecl final : public NamedTypeDecl {
   public:
-	enum Kind { Dtype, Otype, Ftype, Ttype, NUMBER_OF_KINDS };
+	enum Kind { Dtype, DStype, Otype, Ftype, Ttype, ALtype, NUMBER_OF_KINDS };
 
 	Kind kind;
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/Parser/DeclarationNode.cc	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Oct  8 08:03:38 2020
-// Update Count     : 1135
+// Last Modified On : Mon Jan 11 20:58:07 2021
+// Update Count     : 1137
 //
 
@@ -1075,6 +1075,6 @@
 	if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
 		// otype is internally converted to dtype + otype parameters
-		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype };
-		static_assert( sizeof(kindMap)/sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
+		static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::DStype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::ALtype };
+		static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
 		assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
 		TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype, variable.initializer ? variable.initializer->buildType() : nullptr );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/Parser/parser.yy	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jan 11 14:14:16 2021
-// Update Count     : 4630
+// Last Modified On : Mon Jan 11 21:32:10 2021
+// Update Count     : 4633
 //
 
@@ -2449,5 +2449,8 @@
 		{ $$ = DeclarationNode::newTypeParam( $2, $1 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
 	| '[' identifier_or_type_name ']'
-		{ typedefTable.addToScope( *$2, TYPEDEFname, "9" ); }
+		{
+			typedefTable.addToScope( *$2, TYPEDEFname, "9" );
+			$$ = DeclarationNode::newTypeParam( TypeDecl::ALtype, $2 );
+		}
 	// | type_specifier identifier_parameter_declarator
 	| assertion_list
@@ -2461,5 +2464,5 @@
 		{ $$ = TypeDecl::Dtype; }
 	| '*'
-		{ $$ = TypeDecl::Dtype; }						// dtype + sized
+		{ $$ = TypeDecl::DStype; }						// dtype + sized
 	| ELLIPSIS
 		{ $$ = TypeDecl::Ttype; }
Index: src/SymTab/Demangle.cc
===================================================================
--- src/SymTab/Demangle.cc	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/SymTab/Demangle.cc	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jul 19 12:52:41 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb 11 15:09:18 2020
-// Update Count     : 10
+// Last Modified On : Mon Jan 11 21:28:27 2021
+// Update Count     : 11
 //
 
@@ -367,5 +367,5 @@
 				// type variable types
 				for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) {
-					static const std::string typeVariableNames[] = { "DT", "OT", "FT", "TT", };
+					static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", };
 					static_assert(
 						sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS,
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/SymTab/Mangler.cc	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:40:29 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Nov 18 12:01:38 2020
-// Update Count     : 64
+// Last Modified On : Mon Jan 11 21:56:06 2021
+// Update Count     : 74
 //
 #include "Mangler.h"
@@ -313,5 +313,5 @@
 				// and the case has not yet come up in practice. Alternatively, if not then this code can be removed
 				// aside from the assert false.
-				assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
+				assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));
 				assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
 				mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
@@ -343,5 +343,5 @@
 							break;
 						  default:
-							assert( false );
+							assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );
 						} // switch
 						varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
@@ -673,15 +673,15 @@
 					for ( auto & decl : ptype->forall ) {
 						switch ( decl->kind ) {
-						case ast::TypeDecl::Kind::Dtype:
+						  case ast::TypeDecl::Kind::Dtype:
 							dcount++;
 							break;
-						case ast::TypeDecl::Kind::Ftype:
+						  case ast::TypeDecl::Kind::Ftype:
 							fcount++;
 							break;
-						case ast::TypeDecl::Kind::Ttype:
+						  case ast::TypeDecl::Kind::Ttype:
 							vcount++;
 							break;
-						default:
-							assert( false );
+						  default:
+							assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
 						} // switch
 						varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
Index: src/SymTab/ManglerCommon.cc
===================================================================
--- src/SymTab/ManglerCommon.cc	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/SymTab/ManglerCommon.cc	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:44:03 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 13 14:54:38 2019
-// Update Count     : 28
+// Last Modified On : Mon Jan 11 21:23:10 2021
+// Update Count     : 29
 //
 
@@ -104,10 +104,12 @@
 			const std::string typeVariables[] = {
 				"BD", // dtype
+				"BDS", // dtype + sized
 				"BO", // otype
 				"BF", // ftype
 				"BT", // ttype
+				"BAL", // array length type
 			};
 			static_assert(
-				sizeof(typeVariables)/sizeof(typeVariables[0]) == TypeDecl::NUMBER_OF_KINDS,
+				sizeof(typeVariables) / sizeof(typeVariables[0]) == TypeDecl::NUMBER_OF_KINDS,
 				"Each type variable kind should have a corresponding mangler prefix"
 			);
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/SynTree/Declaration.h	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 13 23:11:22 2019
-// Update Count     : 157
+// Last Modified On : Mon Jan 11 20:48:39 2021
+// Update Count     : 158
 //
 
@@ -201,5 +201,5 @@
 	typedef NamedTypeDecl Parent;
   public:
-	enum Kind { Dtype, Otype, Ftype, Ttype, NUMBER_OF_KINDS };
+	enum Kind { Dtype, DStype, Otype, Ftype, Ttype, ALtype, NUMBER_OF_KINDS };
 
 	Kind kind;
Index: src/SynTree/TypeDecl.cc
===================================================================
--- src/SynTree/TypeDecl.cc	(revision 2501ae5ea2193541b80292e9eb68e8a2315fb29a)
+++ src/SynTree/TypeDecl.cc	(revision b66d14aaeea72bcdae48b4628ad29848b32691eb)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Oct  8 18:18:55 2020
-// Update Count     : 22
+// Last Modified On : Mon Jan 11 21:26:50 2021
+// Update Count     : 23
 //
 
@@ -33,5 +33,5 @@
 
 const char * TypeDecl::typeString() const {
-	static const char * kindNames[] = { "sized data type", "sized object type", "sized function type", "sized tuple type" };
+	static const char * kindNames[] = { "data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "array length type" };
 	static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." );
 	assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
@@ -40,5 +40,5 @@
 
 const char * TypeDecl::genTypeString() const {
-	static const char * kindNames[] = { "dtype", "otype", "ftype", "ttype" };
+	static const char * kindNames[] = { "T &", "T *", "T", "(*)", "T ...", "[T]" };
 	static_assert( sizeof(kindNames)/sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "genTypeString: kindNames is out of sync." );
 	assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." );
