Index: src/SymTab/Demangle.cc
===================================================================
--- src/SymTab/Demangle.cc	(revision 0e761e405c325b38ae1fc9d3ac70a15a9a693bc5)
+++ src/SymTab/Demangle.cc	(revision 550e8199e34e770198bf42e022b1f7d3e33effc9)
@@ -369,9 +369,14 @@
 				// type variable types
 				for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) {
+					static const std::string typeVariableNames[] = { "DT", "FT", "TT", };
+					static_assert(
+						sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS,
+						"Each type variable kind should have a demangle name prefix"
+					);
 					parsers.emplace_back(Encoding::typeVariables[k], [k, this](Type::Qualifiers tq) -> TypeInstType * {
 						PRINT( std::cerr << "type variable type: " << k << std::endl; )
-						std::string name;
-						if (! extractName(name)) return nullptr;
-						return new TypeInstType(tq, name, (TypeDecl::Kind)k != TypeDecl::Ftype);
+						size_t N;
+						if (! extractNumber(N)) return nullptr;
+						return new TypeInstType(tq, toString(typeVariableNames[k], N), (TypeDecl::Kind)k != TypeDecl::Ftype);
 					});
 				}
@@ -541,5 +546,9 @@
 					PRINT( std::cerr << acount << " assertions" << std::endl; )
 					if (! expect('_')) return nullptr;
-					// recursively(?) parse `acount` assertions
+					for (size_t i = 0; i < acount; ++i) {
+						// TODO: need to recursively parse assertions, but for now just return nullptr so that
+						// demangler does not crash if there are assertions
+						return nullptr;
+					}
 					if (! expect('_')) return nullptr;
 				}
