Index: src/CodeTools/DeclStats.cc
===================================================================
--- src/CodeTools/DeclStats.cc	(revision 424931dd6af68222c4b2549fae5ee43f3791bd72)
+++ src/CodeTools/DeclStats.cc	(revision f923b5f3ad24f314f2fa278b457d9f7f293676d3)
@@ -18,4 +18,5 @@
 #include <iostream>
 #include <map>
+#include <sstream>
 #include <string>
 #include <unordered_map>
@@ -71,25 +72,4 @@
 				return *this;
 			}
-
-			/// Update based on a declaration list
-			ArgPackStats& operator+= ( std::list<DeclarationWithType*>& decls ) {
-				unsigned nn = 0;
-				unsigned nn_basic = 0;
-				unsigned nn_poly = 0;
-				for ( auto decl : decls ) {
-					nn += decl->get_type()->size();
-					if ( dynamic_cast<BasicType*>( decl->get_type() ) ) ++nn_basic;
-					else if ( GenPoly::hasPolyBase( decl->get_type() ) ) ++nn_poly;
-				}
-				++n.at( nn );
-				++n_basic.at( nn_basic );
-				++n_poly.at( nn_poly );
-				if ( nn > 0 ) {
-					++p_basic[ nn_basic*100/nn ];
-					++p_poly[ nn_poly*100/nn ];
-				}
-				
-				return *this;
-			}
 		};
 		
@@ -100,4 +80,8 @@
 			/// Count of declarations with each name
 			std::unordered_map<std::string, unsigned> by_name;
+			/// Count of uses of each basic type
+			std::unordered_map<std::string, unsigned> basic_type_names;
+			/// Count of uses of each non-basic type
+			std::unordered_map<std::string, unsigned> compound_type_names;
 			/// Stats for the parameter list
 			ArgPackStats params;
@@ -112,5 +96,5 @@
 			ArgPackStats assn_returns;
 			
-			Stats() : n_decls(0), n_type_params(), by_name(), params(), returns(), n_assns(), assn_params(), assn_returns() {}
+			Stats() : n_decls(0), n_type_params(), by_name(), basic_type_names(), compound_type_names(), params(), returns(), n_assns(), assn_params(), assn_returns() {}
 
 		public:
@@ -119,4 +103,6 @@
 				sum( n_type_params, o.n_type_params );
 				sum( by_name, o.by_name );
+				sum( basic_type_names, o.basic_type_names );
+				sum( compound_type_names, o.compound_type_names );
 				sum( params, o.params );
 				sum( returns, o.returns );
@@ -133,7 +119,36 @@
 		Stats total;
 
-		void analyzeFunc( FunctionType* fnTy, ArgPackStats& params, ArgPackStats& returns ) {
-			params += fnTy->get_parameters();
-			returns += fnTy->get_returnVals();
+		/// Update arg pack stats based on a declaration list
+		void analyze( Stats& stats, ArgPackStats& pstats, std::list<DeclarationWithType*>& decls ) {
+			unsigned n = 0;
+			unsigned n_basic = 0;
+			unsigned n_poly = 0;
+			for ( auto decl : decls ) {
+				n += decl->get_type()->size();
+				if ( BasicType* bt = dynamic_cast<BasicType*>( decl->get_type() ) ) {
+					++n_basic;
+					std::stringstream ss;
+					bt->print( ss );
+					++stats.basic_type_names[ ss.str() ];
+				} else if ( GenPoly::hasPolyBase( decl->get_type() ) ) {
+					++n_poly;
+				} else {
+					std::stringstream ss;
+					decl->get_type()->print( ss );
+					++stats.compound_type_names[ ss.str() ];
+				}
+			}
+			++pstats.n.at( n );
+			++pstats.n_basic.at( n_basic );
+			++pstats.n_poly.at( n_poly );
+			if ( n > 0 ) {
+				++pstats.p_basic[ n_basic*100/n ];
+				++pstats.p_poly[ n_poly*100/n ];
+			}
+		}
+		
+		void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) {
+			analyze( stats, params, fnTy->get_parameters() );
+			analyze( stats, returns, fnTy->get_returnVals() );
 		}
 
@@ -164,5 +179,5 @@
 						assnTy = assnDecl->get_functionType();
 					}
-					if ( assnTy ) analyzeFunc( assnTy, stats.assn_params, stats.assn_returns );
+					if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns );
 				}
 			}
@@ -171,5 +186,5 @@
 			++stats.by_name[ decl->get_name() ];
 
-			analyzeFunc( fnTy, stats.params, stats.returns );
+			analyzeFunc( fnTy, stats, stats.params, stats.returns );
 		}
 
@@ -266,4 +281,6 @@
 			printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); });
 			printAllSparseHisto("overloads", [](const Stats& stats) { return stats.by_name; });
+			printAll("basic_type_names", [](const Stats& stats) { return stats.basic_type_names.size(); });
+			printAll("compound_type_names", [](const Stats& stats) { return stats.compound_type_names.size(); });
 			printAllPack("params", [](const Stats& stats) { return stats.params; });
 			printAllPack("returns", [](const Stats& stats) { return stats.returns; });
