Changes in src/CodeTools/DeclStats.cc [a16764a6:bf2438c]
- File:
-
- 1 edited
-
src/CodeTools/DeclStats.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeTools/DeclStats.cc
ra16764a6 rbf2438c 23 23 #include <utility> // for pair, make_pair 24 24 25 #include "Common/ PassVisitor.h"25 #include "Common/SemanticError.h" // for SemanticError 26 26 #include "Common/VectorMap.h" // for VectorMap 27 27 #include "GenPoly/GenPoly.h" // for hasPolyBase … … 35 35 namespace CodeTools { 36 36 37 struct DeclStats : public WithShortCircuiting{37 class DeclStats : public Visitor { 38 38 template<typename T> 39 39 static void sum(T& a, const T& b) { a += b; } … … 61 61 62 62 struct ArgPackStats { 63 VectorMap<unsigned> n; ///< Count of decls with each number of elements 64 VectorMap<unsigned> n_basic; ///< Count of decls with each number of basic type elements 65 VectorMap<unsigned> n_generic; ///< Count of decls with each number of generic type elements 66 VectorMap<unsigned> n_poly; ///< Count of decls with each number of polymorphic elements 67 VectorMap<unsigned> n_compound; ///< Count of decls with each number of non-generic compound types 68 std::map<unsigned, unsigned> p_basic; ///< Count of decls with each percentage of basic type elements 69 std::map<unsigned, unsigned> p_generic; ///< Count of decls with each percentage of generic type elements 70 std::map<unsigned, unsigned> p_poly; ///< Count of decls with each percentage of polymorphic elements 71 std::map<unsigned, unsigned> p_compound; ///< Count of decls with each percentage of non-generic compound type elements 72 VectorMap<unsigned> n_types; ///< Count of decls with each number of distinct types in the pack 63 VectorMap<unsigned> n; ///< Count of decls with each number of elements 64 VectorMap<unsigned> n_basic; ///< Count of decls with each number of basic type elements 65 VectorMap<unsigned> n_poly; ///< Count of decls with each number of polymorphic elements 66 std::map<unsigned, unsigned> p_basic; ///< Count of decls with each percentage of basic type elements 67 std::map<unsigned, unsigned> p_poly; ///< Count of decls with each percentage of polymorphic elements 68 VectorMap<unsigned> n_types; ///< Count of decls with each number of distinct types in the pack 73 69 /// Count of decls with each percentage of new types in lists. 74 70 /// Types used in the parameter list that recur in the return list are not considered to be new. … … 78 74 sum(n, o.n); 79 75 sum(n_basic, o.n_basic); 80 sum(n_generic, o.n_generic);81 76 sum(n_poly, o.n_poly); 82 sum(n_compound, o.n_compound);83 77 sum(p_basic, o.p_basic); 84 sum(p_generic, o.p_generic);85 78 sum(p_poly, o.p_poly); 86 sum(p_compound, o.p_compound);87 79 sum(n_types, o.n_types); 88 80 sum(p_new, o.p_new); … … 96 88 /// Count of declarations with each number of assertion parameters 97 89 VectorMap<unsigned> n_type_params; 98 /// Count of generic types with each number of type parameters99 VectorMap<unsigned> n_generic_params;100 /// Count of maximum nesting depth of types101 VectorMap<unsigned> n_generic_nesting;102 90 /// Count of declarations with each name 103 91 std::unordered_map<std::string, unsigned> by_name; 104 92 /// Count of uses of each basic type 105 93 std::unordered_map<std::string, unsigned> basic_type_names; 106 /// Count of uses of each generic type name (includes "*", "[]", "(*)", "[,]") 107 std::unordered_map<std::string, unsigned> generic_type_names; 108 /// Count of uses of each non-generic aggregate type 94 /// Count of uses of each non-basic type 109 95 std::unordered_map<std::string, unsigned> compound_type_names; 110 96 /// Count of decls using each basic type 111 97 std::unordered_map<std::string, unsigned> basic_type_decls; 112 /// Count of decls using each generic type (includes "*", "[]", "(*)", "[,]")113 std::unordered_map<std::string, unsigned> generic_type_decls;114 98 /// Count of decls using each compound type 115 99 std::unordered_map<std::string, unsigned> compound_type_decls; … … 126 110 ArgPackStats assn_returns; 127 111 128 Stats() : n_decls(0), n_type_params(), n_generic_params(), n_generic_nesting(), 129 by_name(), basic_type_names(), generic_type_names(), compound_type_names(), 130 basic_type_decls(), generic_type_decls(), compound_type_decls(), params(), 131 returns(), n_assns(), assn_params(), assn_returns() {} 112 Stats() : n_decls(0), n_type_params(), by_name(), basic_type_names(), compound_type_names(), basic_type_decls(), compound_type_decls(), params(), returns(), n_assns(), assn_params(), assn_returns() {} 132 113 133 114 public: … … 135 116 sum( n_decls, o.n_decls ); 136 117 sum( n_type_params, o.n_type_params ); 137 sum( n_generic_params, o.n_generic_params );138 sum( n_generic_nesting, o.n_generic_nesting );139 118 sum( by_name, o.by_name ); 140 119 sum( basic_type_names, o.basic_type_names ); 141 sum( generic_type_names, o.generic_type_names );142 120 sum( compound_type_names, o.compound_type_names ); 143 121 sum( basic_type_decls, o.basic_type_decls ); 144 sum( generic_type_decls, o.generic_type_decls );145 122 sum( compound_type_decls, o.compound_type_decls ); 146 123 sum( params, o.params ); … … 154 131 }; 155 132 156 /// number of counting bins for linkages 157 static const unsigned n_named_specs = 8; 158 /// map from total number of specs to bins 159 static const unsigned ind_for_linkage[16]; 160 161 Stats for_linkage[n_named_specs]; ///< Stores separate stats per linkage 133 Stats for_linkage[LinkageSpec::NoOfSpecs]; ///< Stores separate stats per linkage 162 134 std::unordered_set<std::string> seen_names; ///< Stores manglenames already seen to avoid double-counting 163 135 Stats total; … … 165 137 std::map<std::pair<unsigned, unsigned>, unsigned> exprs_by_fanout_at_depth; 166 138 167 void countType( const std::string& name, unsigned& n, std::unordered_map<std::string,168 unsigned>& names, std::unordered_map<std::string, unsigned>& decls,169 std::unordered_set<std::string>& elSeen ) {170 ++n;171 ++names[ name ];172 if ( elSeen.insert( name ).second ) { ++decls[ name ]; }173 }174 175 void update_max( unsigned& max, unsigned crnt ) {176 if ( crnt > max ) max = crnt;177 }178 179 void analyzeSubtype( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen,180 unsigned& n_poly, bool& seen_poly, unsigned& max_depth, unsigned depth ) {181 unsigned x;182 analyzeType( ty, stats, elSeen, x, x, n_poly, x, seen_poly, max_depth, depth + 1 );183 }184 185 void analyzeSubtypes( std::list<DeclarationWithType*>& tys, Stats& stats,186 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,187 unsigned& max_depth, unsigned depth, unsigned& n_subs ) {188 for ( DeclarationWithType* dwt : tys ) {189 Type* ty = dwt->get_type();190 n_subs += (unsigned)( dynamic_cast<VoidType*>(ty) != nullptr );191 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );192 }193 }194 195 void analyzeSubtypes( std::list<Expression*>& tys, Stats& stats,196 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,197 unsigned& max_depth, unsigned depth ) {198 for ( Expression* expr : tys ) {199 TypeExpr* texpr = dynamic_cast<TypeExpr*>(expr);200 if ( ! texpr ) continue;201 Type* ty = texpr->get_type();202 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );203 }204 }205 206 void analyzeSubtypes( std::list<Type*>& tys, Stats& stats,207 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,208 unsigned& max_depth, unsigned depth ) {209 for ( Type* ty : tys ) {210 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );211 }212 }213 214 void analyzeType( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen,215 unsigned& n_basic, unsigned& n_generic, unsigned& n_poly, unsigned& n_agg,216 bool& seen_poly, unsigned& max_depth, unsigned depth = 0 ) {217 if ( BasicType* bt = dynamic_cast<BasicType*>(ty) ) {218 std::string name = BasicType::typeNames[ bt->get_kind() ];219 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );220 update_max( max_depth, depth );221 } else if ( PointerType* pt = dynamic_cast<PointerType*>(ty) ) {222 std::string name = "*";223 countType(224 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);225 analyzeSubtype(226 pt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );227 ++stats.n_generic_params.at( 1 );228 } else if ( ArrayType* at = dynamic_cast<ArrayType*>(ty) ) {229 std::string name = "[]";230 countType(231 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);232 analyzeSubtype(233 at->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );234 ++stats.n_generic_params.at( 1 );235 } else if ( ReferenceType* rt = dynamic_cast<ReferenceType*>(ty) ) {236 std::string name = "&";237 countType(238 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);239 analyzeSubtype(240 rt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );241 ++stats.n_generic_params.at( 1 );242 } else if ( FunctionType* ft = dynamic_cast<FunctionType*>(ty) ) {243 std::string name = "(*)";244 countType(245 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);246 unsigned n_subs = 0;247 analyzeSubtypes(248 ft->get_returnVals(), stats, elSeen, n_poly, seen_poly, max_depth, depth,249 n_subs );250 analyzeSubtypes(251 ft->get_parameters(), stats, elSeen, n_poly, seen_poly, max_depth, depth,252 n_subs );253 ++stats.n_generic_params.at( n_subs );254 } else if ( TypeInstType* vt = dynamic_cast<TypeInstType*>(ty) ) {255 if ( ! seen_poly ) {256 ++n_poly;257 seen_poly = true;258 }259 countType(260 vt->get_name(), n_agg, stats.compound_type_names, stats.compound_type_decls,261 elSeen );262 update_max( max_depth, depth );263 } else if ( ReferenceToType* st = dynamic_cast<ReferenceToType*>(ty) ) {264 std::list<Expression*>& params = st->get_parameters();265 if ( params.empty() ) {266 countType(267 st->get_name(), n_agg, stats.compound_type_names,268 stats.compound_type_decls, elSeen );269 update_max( max_depth, depth );270 } else {271 countType(272 st->get_name(), n_generic, stats.generic_type_names,273 stats.generic_type_decls, elSeen);274 analyzeSubtypes( params, stats, elSeen, n_poly, seen_poly, max_depth, depth );275 ++stats.n_generic_params.at( params.size() );276 }277 } else if ( TupleType* tt = dynamic_cast<TupleType*>(ty) ) {278 std::string name = "[,]";279 countType(280 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);281 analyzeSubtypes(282 tt->get_types(), stats, elSeen, n_poly, seen_poly, max_depth, depth );283 ++stats.n_generic_params.at( tt->size() );284 } else if ( dynamic_cast<VarArgsType*>(ty) ) {285 std::string name = "...";286 countType(287 name, n_agg, stats.compound_type_names, stats.compound_type_decls, elSeen );288 update_max( max_depth, depth );289 } else if ( dynamic_cast<ZeroType*>(ty) ) {290 std::string name = "0";291 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );292 update_max( max_depth, depth );293 } else if ( dynamic_cast<OneType*>(ty) ) {294 std::string name = "1";295 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );296 update_max( max_depth, depth );297 }298 }299 300 139 /// Update arg pack stats based on a declaration list 301 void analyze( Stats& stats, std::unordered_set<std::string>& seen, 302 std::unordered_set<std::string>& elSeen, ArgPackStats& pstats, 303 std::list<DeclarationWithType*>& decls ) { 140 void analyze( Stats& stats, std::unordered_set<std::string>& seen, ArgPackStats& pstats, std::list<DeclarationWithType*>& decls ) { 304 141 std::unordered_set<std::string> types; 305 unsigned n = 0; ///< number of args/returns 306 unsigned n_basic = 0; ///< number of basic types 307 unsigned n_generic = 0; ///< number of generic types (includes "*", "&", "[]", "(*)", "[,]") 308 unsigned n_poly = 0; ///< number of polymorphic types 309 unsigned n_agg = 0; ///< number of non-generic aggregate types 310 unsigned n_new = 0; ///< number of new types 311 142 unsigned n = 0; ///< number of args/returns 143 unsigned n_basic = 0; ///< number of basic types 144 unsigned n_poly = 0; ///< number of polymorphic types 145 unsigned n_new = 0; ///< number of new types 312 146 for ( auto decl : decls ) { 313 147 Type* dt = decl->get_type(); … … 318 152 dt->print( ss ); 319 153 types.insert( ss.str() ); 320 if ( seen.insert( ss.str() ).second ) { ++n_new; } 321 322 bool seen_poly = false; 323 unsigned max_depth = 0; 324 analyzeType( 325 dt, stats, elSeen, n_basic, n_generic, n_poly, n_agg, seen_poly, max_depth ); 326 ++stats.n_generic_nesting.at( max_depth ); 327 } 328 154 bool this_new = seen.insert( ss.str() ).second; 155 if ( this_new ) { ++n_new; } 156 157 if ( dynamic_cast<BasicType*>( dt ) ) { 158 ++n_basic; 159 ++stats.basic_type_names[ ss.str() ]; 160 if ( this_new ) { 161 ++stats.basic_type_decls[ ss.str() ]; 162 } 163 } else if ( GenPoly::hasPolyBase( dt ) ) { 164 ++n_poly; 165 } else { 166 ++stats.compound_type_names[ ss.str() ]; 167 if ( this_new ) { 168 ++stats.compound_type_decls[ ss.str() ]; 169 } 170 } 171 } 329 172 ++pstats.n.at( n ); 330 173 ++pstats.n_basic.at( n_basic ); 331 ++pstats.n_generic.at( n_generic );332 174 ++pstats.n_poly.at( n_poly ); 333 ++pstats.n_compound.at( n_agg );334 175 if ( n > 0 ) { 335 176 ++pstats.p_basic[ n_basic*100/n ]; 336 ++pstats.p_generic[ n_generic*100/n ];337 177 ++pstats.p_poly[ n_poly*100/n ]; 338 ++pstats.p_compound[ n_agg*100/n ]; 339 if ( n > 1 ) ++pstats.p_new[ (n_new-1)*100/(n-1) ]; 178 ++pstats.p_new[ n_new*100/n ]; 340 179 } 341 180 ++pstats.n_types.at( types.size() ); … … 344 183 void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) { 345 184 std::unordered_set<std::string> seen; 346 std::unordered_set<std::string> elSeen; 347 analyze( stats, seen, elSeen, params, fnTy->get_parameters() ); 348 analyze( stats, seen, elSeen, returns, fnTy->get_returnVals() ); 185 analyze( stats, seen, params, fnTy->get_parameters() ); 186 analyze( stats, seen, returns, fnTy->get_returnVals() ); 349 187 } 350 188 … … 362 200 363 201 public: 364 void previsit( FunctionDecl *decl ) { 202 using Visitor::visit; 203 204 virtual void visit( FunctionDecl *decl ) { 365 205 // skip if already seen declaration for this function 366 const std::string& mangleName = decl->get_mangleName().empty() ? decl->name : decl->get_mangleName(); 367 if ( seen_names.insert( mangleName ).second ) { 368 Stats& stats = for_linkage[ ind_for_linkage[ decl->linkage ] ]; 369 370 ++stats.n_decls; 371 FunctionType* fnTy = decl->type; 372 const Type::ForallList& forall = fnTy->forall; 373 ++stats.n_type_params.at( forall.size() ); 374 unsigned n_assns = 0; 375 for ( TypeDecl* fdecl : forall ) { 376 n_assns += fdecl->assertions.size(); 377 for ( DeclarationWithType* assn : fdecl->assertions ) { 378 FunctionType *assnTy = nullptr; 379 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 380 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 381 assnTy = dynamic_cast<FunctionType*>(ptrTy->base); 382 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 383 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 384 assnTy = assnDecl->type; 385 } 386 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 206 const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName(); 207 if ( ! seen_names.insert( mangleName ).second ) { 208 maybeAccept( decl->get_statements(), *this ); 209 return; 210 } 211 212 Stats& stats = for_linkage[ decl->get_linkage() ]; 213 214 ++stats.n_decls; 215 FunctionType* fnTy = decl->get_functionType(); 216 const Type::ForallList& forall = fnTy->get_forall(); 217 ++stats.n_type_params.at( forall.size() ); 218 unsigned n_assns = 0; 219 for ( TypeDecl* fdecl : forall ) { 220 n_assns += fdecl->get_assertions().size(); 221 for ( DeclarationWithType* assn : fdecl->get_assertions() ) { 222 FunctionType *assnTy = 0; 223 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 224 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 225 assnTy = dynamic_cast<FunctionType*>(ptrTy->get_base()); 226 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 227 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 228 assnTy = assnDecl->get_functionType(); 387 229 } 388 } 389 ++stats.n_assns[ n_assns ]; 390 ++stats.by_name[ decl->name ]; 391 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 392 } 393 } 394 395 void previsit( UntypedExpr *expr ) { 396 visit_children = false; 230 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 231 } 232 } 233 ++stats.n_assns[ n_assns ]; 234 235 ++stats.by_name[ decl->get_name() ]; 236 237 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 238 239 // analyze expressions in decl statements 240 maybeAccept( decl->get_statements(), *this ); 241 } 242 243 virtual void visit( UntypedExpr *expr ) { 397 244 analyzeExpr( expr, 0 ); 398 245 } … … 425 272 template<typename F> 426 273 void printAllHisto( const std::string& name, F extract ) { 427 VectorMap<unsigned> histos[ n_named_specs];274 VectorMap<unsigned> histos[LinkageSpec::NoOfSpecs]; 428 275 VectorMap<unsigned> thisto; 429 276 430 277 for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); } 431 278 432 for ( unsigned i = 0; i < n_named_specs; ++i ) {279 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 433 280 // can't be a higher count in one of the sub-histograms than the total 434 281 histos[i].reserve( thisto.size() ); … … 448 295 template<typename F> 449 296 void printAllSparseHisto( const std::string& name, F extract ) { 450 std::map<unsigned, unsigned> histos[ n_named_specs];297 std::map<unsigned, unsigned> histos[LinkageSpec::NoOfSpecs]; 451 298 std::map<unsigned, unsigned> thisto; 452 299 453 300 for ( const auto& entry : extract(total) ) { ++thisto[ entry.second ]; } 454 301 455 for ( unsigned i = 0; i < n_named_specs; ++i ) {302 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 456 303 for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; } 457 304 } … … 460 307 const auto& key = entry.first; 461 308 std::cout << "\"" << name << "\"," << key; 462 for ( unsigned i = 0; i < n_named_specs; ++i ) {309 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 463 310 auto it = histos[i].find( key ); 464 311 if ( it == histos[i].end() ) std::cout << ",0"; … … 472 319 void printAllPack( const std::string& name, F extract ) { 473 320 printAllMap("n_basic_" + name, [&extract](const Stats& stats) { return extract(stats).n_basic; }); 474 printAllMap("n_generic_" + name, [&extract](const Stats& stats) { return extract(stats).n_generic; });475 321 printAllMap("n_poly_" + name, [&extract](const Stats& stats) { return extract(stats).n_poly; }); 476 printAllMap("n_compound_" + name, [&extract](const Stats& stats) { return extract(stats).n_compound; });477 322 printAllMap("n_" + name, [&extract](const Stats& stats) { return extract(stats).n; }); 478 323 printAllMap("%_basic_" + name, [&extract](const Stats& stats) { return extract(stats).p_basic; }); 479 printAllMap("%_generic_" + name, [&extract](const Stats& stats) { return extract(stats).p_generic; });480 324 printAllMap("%_poly_" + name, [&extract](const Stats& stats) { return extract(stats).p_poly; }); 481 printAllMap("%_compound_" + name, [&extract](const Stats& stats) { return extract(stats).p_compound; });482 325 printAllMap("n_distinct_types_" + name, [&extract](const Stats& stats) { return extract(stats).n_types; }); 483 326 printAllMap("%_new_types_in_" + name, [&extract](const Stats& stats) { return extract(stats).p_new; }); … … 499 342 } 500 343 501 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\" compiler\",\"builtinCFA\",\"builtinC\",\"other\",\"TOTAL\"" << std::endl;344 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"builtin\",\"TOTAL\"" << std::endl; 502 345 503 346 printAllMap("n_type_params", [](const Stats& stats) { return stats.n_type_params; }); 504 printAllMap("n_generic_params", [](const Stats& stats) { return stats.n_generic_params; });505 printAllMap("n_generic_nesting", [](const Stats& stats) { return stats.n_generic_nesting; });506 347 printAll("n_decls", [](const Stats& stats) { return stats.n_decls; }); 507 348 printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); }); … … 510 351 printAllSparseHisto("basic_type_uses", [](const Stats& stats) { return stats.basic_type_names; }); 511 352 printAllSparseHisto("decls_using_basic_type", [](const Stats& stats) { return stats.basic_type_decls; }); 512 printAll("generic_type_names", [](const Stats& stats) { return stats.generic_type_names.size(); });513 printAllSparseHisto("generic_type_uses", [](const Stats& stats) { return stats.generic_type_names; });514 printAllSparseHisto("decls_using_generic_type", [](const Stats& stats) { return stats.generic_type_decls; });515 353 printAll("compound_type_names", [](const Stats& stats) { return stats.compound_type_names.size(); }); 516 354 printAllSparseHisto("compound_type_uses", [](const Stats& stats) { return stats.compound_type_names; }); … … 527 365 }; 528 366 529 const unsigned DeclStats::ind_for_linkage[]530 = { 7, 7, 2, 1, 7, 7, 7, 3, 4, 7, 6, 5, 7, 7, 7, 0 };531 532 367 void printDeclStats( std::list< Declaration * > &translationUnit ) { 533 PassVisitor<DeclStats>stats;368 DeclStats stats; 534 369 acceptAll( translationUnit, stats ); 535 stats.p ass.print();370 stats.print(); 536 371 } 537 372
Note:
See TracChangeset
for help on using the changeset viewer.