Changes in src/CodeTools/DeclStats.cc [326cd2b:e5c74d1]
- File:
-
- 1 edited
-
src/CodeTools/DeclStats.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeTools/DeclStats.cc
r326cd2b re5c74d1 23 23 #include <utility> // for pair, make_pair 24 24 25 #include "Common/PassVisitor.h" 25 26 #include "Common/SemanticError.h" // for SemanticError 26 27 #include "Common/VectorMap.h" // for VectorMap … … 35 36 namespace CodeTools { 36 37 37 class DeclStats : public Visitor{38 struct DeclStats : public WithShortCircuiting { 38 39 template<typename T> 39 40 static void sum(T& a, const T& b) { a += b; } … … 61 62 62 63 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 64 VectorMap<unsigned> n; ///< Count of decls with each number of elements 65 VectorMap<unsigned> n_basic; ///< Count of decls with each number of basic type elements 66 VectorMap<unsigned> n_poly; ///< Count of decls with each number of polymorphic elements 67 std::map<unsigned, unsigned> p_basic; ///< Count of decls with each percentage of basic type elements 68 std::map<unsigned, unsigned> p_poly; ///< Count of decls with each percentage of polymorphic elements 69 VectorMap<unsigned> n_types; ///< Count of decls with each number of distinct types in the pack 73 70 /// Count of decls with each percentage of new types in lists. 74 71 /// Types used in the parameter list that recur in the return list are not considered to be new. … … 78 75 sum(n, o.n); 79 76 sum(n_basic, o.n_basic); 80 sum(n_generic, o.n_generic);81 77 sum(n_poly, o.n_poly); 82 sum(n_compound, o.n_compound);83 78 sum(p_basic, o.p_basic); 84 sum(p_generic, o.p_generic);85 79 sum(p_poly, o.p_poly); 86 sum(p_compound, o.p_compound);87 80 sum(n_types, o.n_types); 88 81 sum(p_new, o.p_new); … … 96 89 /// Count of declarations with each number of assertion parameters 97 90 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 91 /// Count of declarations with each name 103 92 std::unordered_map<std::string, unsigned> by_name; 104 93 /// Count of uses of each basic type 105 94 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 95 /// Count of uses of each non-basic type 109 96 std::unordered_map<std::string, unsigned> compound_type_names; 110 97 /// Count of decls using each basic type 111 98 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 99 /// Count of decls using each compound type 115 100 std::unordered_map<std::string, unsigned> compound_type_decls; … … 126 111 ArgPackStats assn_returns; 127 112 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() {} 113 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 114 133 115 public: … … 135 117 sum( n_decls, o.n_decls ); 136 118 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 119 sum( by_name, o.by_name ); 140 120 sum( basic_type_names, o.basic_type_names ); 141 sum( generic_type_names, o.generic_type_names );142 121 sum( compound_type_names, o.compound_type_names ); 143 122 sum( basic_type_decls, o.basic_type_decls ); 144 sum( generic_type_decls, o.generic_type_decls );145 123 sum( compound_type_decls, o.compound_type_decls ); 146 124 sum( params, o.params ); … … 154 132 }; 155 133 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 134 Stats for_linkage[LinkageSpec::NoOfSpecs]; ///< Stores separate stats per linkage 162 135 std::unordered_set<std::string> seen_names; ///< Stores manglenames already seen to avoid double-counting 163 136 Stats total; … … 165 138 std::map<std::pair<unsigned, unsigned>, unsigned> exprs_by_fanout_at_depth; 166 139 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 140 /// 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 ) { 141 void analyze( Stats& stats, std::unordered_set<std::string>& seen, ArgPackStats& pstats, std::list<DeclarationWithType*>& decls ) { 304 142 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 143 unsigned n = 0; ///< number of args/returns 144 unsigned n_basic = 0; ///< number of basic types 145 unsigned n_poly = 0; ///< number of polymorphic types 146 unsigned n_new = 0; ///< number of new types 312 147 for ( auto decl : decls ) { 313 148 Type* dt = decl->get_type(); … … 318 153 dt->print( ss ); 319 154 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 155 bool this_new = seen.insert( ss.str() ).second; 156 if ( this_new ) { ++n_new; } 157 158 if ( dynamic_cast<BasicType*>( dt ) ) { 159 ++n_basic; 160 ++stats.basic_type_names[ ss.str() ]; 161 if ( this_new ) { 162 ++stats.basic_type_decls[ ss.str() ]; 163 } 164 } else if ( GenPoly::hasPolyBase( dt ) ) { 165 ++n_poly; 166 } else { 167 ++stats.compound_type_names[ ss.str() ]; 168 if ( this_new ) { 169 ++stats.compound_type_decls[ ss.str() ]; 170 } 171 } 172 } 329 173 ++pstats.n.at( n ); 330 174 ++pstats.n_basic.at( n_basic ); 331 ++pstats.n_generic.at( n_generic );332 175 ++pstats.n_poly.at( n_poly ); 333 ++pstats.n_compound.at( n_agg );334 176 if ( n > 0 ) { 335 177 ++pstats.p_basic[ n_basic*100/n ]; 336 ++pstats.p_generic[ n_generic*100/n ];337 178 ++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) ]; 179 ++pstats.p_new[ n_new*100/n ]; 340 180 } 341 181 ++pstats.n_types.at( types.size() ); … … 344 184 void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) { 345 185 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() ); 186 analyze( stats, seen, params, fnTy->get_parameters() ); 187 analyze( stats, seen, returns, fnTy->get_returnVals() ); 349 188 } 350 189 … … 362 201 363 202 public: 364 using Visitor::visit; 365 366 virtual void visit( FunctionDecl *decl ) { 203 void previsit( FunctionDecl *decl ) { 367 204 // skip if already seen declaration for this function 368 const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName(); 369 if ( ! seen_names.insert( mangleName ).second ) { 370 maybeAccept( decl->get_statements(), *this ); 371 return; 372 } 373 374 Stats& stats = for_linkage[ ind_for_linkage[ decl->get_linkage() ] ]; 375 376 ++stats.n_decls; 377 FunctionType* fnTy = decl->get_functionType(); 378 const Type::ForallList& forall = fnTy->get_forall(); 379 ++stats.n_type_params.at( forall.size() ); 380 unsigned n_assns = 0; 381 for ( TypeDecl* fdecl : forall ) { 382 n_assns += fdecl->get_assertions().size(); 383 for ( DeclarationWithType* assn : fdecl->get_assertions() ) { 384 FunctionType *assnTy = 0; 385 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 386 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 387 assnTy = dynamic_cast<FunctionType*>(ptrTy->get_base()); 388 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 389 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 390 assnTy = assnDecl->get_functionType(); 205 const std::string& mangleName = decl->get_mangleName().empty() ? decl->name : decl->get_mangleName(); 206 if ( seen_names.insert( mangleName ).second ) { 207 Stats& stats = for_linkage[ decl->linkage ]; 208 209 ++stats.n_decls; 210 FunctionType* fnTy = decl->type; 211 const Type::ForallList& forall = fnTy->forall; 212 ++stats.n_type_params.at( forall.size() ); 213 unsigned n_assns = 0; 214 for ( TypeDecl* fdecl : forall ) { 215 n_assns += fdecl->assertions.size(); 216 for ( DeclarationWithType* assn : fdecl->assertions ) { 217 FunctionType *assnTy = nullptr; 218 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 219 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 220 assnTy = dynamic_cast<FunctionType*>(ptrTy->get_base()); 221 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 222 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 223 assnTy = assnDecl->type; 224 } 225 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 391 226 } 392 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 393 } 394 } 395 ++stats.n_assns[ n_assns ]; 396 397 ++stats.by_name[ decl->get_name() ]; 398 399 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 400 401 // analyze expressions in decl statements 402 maybeAccept( decl->get_statements(), *this ); 403 } 404 405 virtual void visit( UntypedExpr *expr ) { 227 } 228 ++stats.n_assns[ n_assns ]; 229 230 ++stats.by_name[ decl->get_name() ]; 231 232 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 233 } 234 } 235 236 void previsit( UntypedExpr *expr ) { 237 visit_children = false; 406 238 analyzeExpr( expr, 0 ); 407 239 } … … 434 266 template<typename F> 435 267 void printAllHisto( const std::string& name, F extract ) { 436 VectorMap<unsigned> histos[ n_named_specs];268 VectorMap<unsigned> histos[LinkageSpec::NoOfSpecs]; 437 269 VectorMap<unsigned> thisto; 438 270 439 271 for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); } 440 272 441 for ( unsigned i = 0; i < n_named_specs; ++i ) {273 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 442 274 // can't be a higher count in one of the sub-histograms than the total 443 275 histos[i].reserve( thisto.size() ); … … 457 289 template<typename F> 458 290 void printAllSparseHisto( const std::string& name, F extract ) { 459 std::map<unsigned, unsigned> histos[ n_named_specs];291 std::map<unsigned, unsigned> histos[LinkageSpec::NoOfSpecs]; 460 292 std::map<unsigned, unsigned> thisto; 461 293 462 294 for ( const auto& entry : extract(total) ) { ++thisto[ entry.second ]; } 463 295 464 for ( unsigned i = 0; i < n_named_specs; ++i ) {296 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 465 297 for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; } 466 298 } … … 469 301 const auto& key = entry.first; 470 302 std::cout << "\"" << name << "\"," << key; 471 for ( unsigned i = 0; i < n_named_specs; ++i ) {303 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) { 472 304 auto it = histos[i].find( key ); 473 305 if ( it == histos[i].end() ) std::cout << ",0"; … … 481 313 void printAllPack( const std::string& name, F extract ) { 482 314 printAllMap("n_basic_" + name, [&extract](const Stats& stats) { return extract(stats).n_basic; }); 483 printAllMap("n_generic_" + name, [&extract](const Stats& stats) { return extract(stats).n_generic; });484 315 printAllMap("n_poly_" + name, [&extract](const Stats& stats) { return extract(stats).n_poly; }); 485 printAllMap("n_compound_" + name, [&extract](const Stats& stats) { return extract(stats).n_compound; });486 316 printAllMap("n_" + name, [&extract](const Stats& stats) { return extract(stats).n; }); 487 317 printAllMap("%_basic_" + name, [&extract](const Stats& stats) { return extract(stats).p_basic; }); 488 printAllMap("%_generic_" + name, [&extract](const Stats& stats) { return extract(stats).p_generic; });489 318 printAllMap("%_poly_" + name, [&extract](const Stats& stats) { return extract(stats).p_poly; }); 490 printAllMap("%_compound_" + name, [&extract](const Stats& stats) { return extract(stats).p_compound; });491 319 printAllMap("n_distinct_types_" + name, [&extract](const Stats& stats) { return extract(stats).n_types; }); 492 320 printAllMap("%_new_types_in_" + name, [&extract](const Stats& stats) { return extract(stats).p_new; }); … … 508 336 } 509 337 510 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\" compiler\",\"builtinCFA\",\"builtinC\",\"other\",\"TOTAL\"" << std::endl;338 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"builtin\",\"TOTAL\"" << std::endl; 511 339 512 340 printAllMap("n_type_params", [](const Stats& stats) { return stats.n_type_params; }); 513 printAllMap("n_generic_params", [](const Stats& stats) { return stats.n_generic_params; });514 printAllMap("n_generic_nesting", [](const Stats& stats) { return stats.n_generic_nesting; });515 341 printAll("n_decls", [](const Stats& stats) { return stats.n_decls; }); 516 342 printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); }); … … 519 345 printAllSparseHisto("basic_type_uses", [](const Stats& stats) { return stats.basic_type_names; }); 520 346 printAllSparseHisto("decls_using_basic_type", [](const Stats& stats) { return stats.basic_type_decls; }); 521 printAll("generic_type_names", [](const Stats& stats) { return stats.generic_type_names.size(); });522 printAllSparseHisto("generic_type_uses", [](const Stats& stats) { return stats.generic_type_names; });523 printAllSparseHisto("decls_using_generic_type", [](const Stats& stats) { return stats.generic_type_decls; });524 347 printAll("compound_type_names", [](const Stats& stats) { return stats.compound_type_names.size(); }); 525 348 printAllSparseHisto("compound_type_uses", [](const Stats& stats) { return stats.compound_type_names; }); … … 536 359 }; 537 360 538 const unsigned DeclStats::ind_for_linkage[]539 = { 7, 7, 2, 1, 7, 7, 7, 3, 4, 7, 6, 5, 7, 7, 7, 0 };540 541 361 void printDeclStats( std::list< Declaration * > &translationUnit ) { 542 DeclStatsstats;362 PassVisitor<DeclStats> stats; 543 363 acceptAll( translationUnit, stats ); 544 stats.p rint();364 stats.pass.print(); 545 365 } 546 366
Note:
See TracChangeset
for help on using the changeset viewer.