Changeset eef8dfb for src/AST/SymbolTable.cpp
- Timestamp:
- Jan 7, 2021, 2:55:57 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 58fe85a
- Parents:
- bdfc032 (diff), 44e37ef (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/SymbolTable.cpp
rbdfc032 reef8dfb 95 95 } 96 96 97 SymbolTable::SpecialFunctionKind SymbolTable::getSpecialFunctionKind(const std::string & name) { 98 if (name == "?{}") return CTOR; 99 if (name == "^?{}") return DTOR; 100 if (name == "?=?") return ASSIGN; 101 return NUMBER_OF_KINDS; 102 } 103 97 104 std::vector<SymbolTable::IdData> SymbolTable::lookupId( const std::string &id ) const { 105 static Stats::Counters::CounterGroup * name_lookup_stats = Stats::Counters::build<Stats::Counters::CounterGroup>("Name Lookup Stats"); 106 static std::map<std::string, Stats::Counters::SimpleCounter *> lookups_by_name; 107 static std::map<std::string, Stats::Counters::SimpleCounter *> candidates_by_name; 108 109 SpecialFunctionKind kind = getSpecialFunctionKind(id); 110 if (kind != NUMBER_OF_KINDS) return specialLookupId(kind); 111 98 112 ++*stats().lookup_calls; 99 113 if ( ! idTable ) return {}; … … 107 121 out.push_back( decl.second ); 108 122 } 123 124 if (Stats::Counters::enabled) { 125 if (! lookups_by_name.count(id)) { 126 // leaks some strings, but it is because Counters do not hold them 127 auto lookupCounterName = new std::string(id + "%count"); 128 auto candidatesCounterName = new std::string(id + "%candidate"); 129 lookups_by_name.emplace(id, new Stats::Counters::SimpleCounter(lookupCounterName->c_str(), name_lookup_stats)); 130 candidates_by_name.emplace(id, new Stats::Counters::SimpleCounter(candidatesCounterName->c_str(), name_lookup_stats)); 131 } 132 (*lookups_by_name[id]) ++; 133 *candidates_by_name[id] += out.size(); 134 } 135 136 return out; 137 } 138 139 std::vector<SymbolTable::IdData> SymbolTable::specialLookupId( SymbolTable::SpecialFunctionKind kind, const std::string & otypeKey ) const { 140 static Stats::Counters::CounterGroup * special_stats = Stats::Counters::build<Stats::Counters::CounterGroup>("Special Lookups"); 141 static Stats::Counters::SimpleCounter * stat_counts[3] = { 142 Stats::Counters::build<Stats::Counters::SimpleCounter>("constructor - count", special_stats), 143 Stats::Counters::build<Stats::Counters::SimpleCounter>("destructor - count", special_stats), 144 Stats::Counters::build<Stats::Counters::SimpleCounter>("assignment - count", special_stats) 145 }; 146 147 static Stats::Counters::SimpleCounter * stat_candidates[3] = { 148 Stats::Counters::build<Stats::Counters::SimpleCounter>("constructor - candidates", special_stats), 149 Stats::Counters::build<Stats::Counters::SimpleCounter>("destructor - candidates", special_stats), 150 Stats::Counters::build<Stats::Counters::SimpleCounter>("assignment - candidates", special_stats) 151 }; 152 153 static Stats::Counters::SimpleCounter * num_lookup_with_key 154 = Stats::Counters::build<Stats::Counters::SimpleCounter>("keyed lookups", special_stats); 155 static Stats::Counters::SimpleCounter * num_lookup_without_key 156 = Stats::Counters::build<Stats::Counters::SimpleCounter>("unkeyed lookups", special_stats); 157 158 assert (kind != NUMBER_OF_KINDS); 159 ++*stats().lookup_calls; 160 if ( ! specialFunctionTable[kind] ) return {}; 161 162 std::vector<IdData> out; 163 164 if (otypeKey.empty()) { // returns everything 165 ++*num_lookup_without_key; 166 for (auto & table : *specialFunctionTable[kind]) { 167 for (auto & decl : *table.second) { 168 out.push_back(decl.second); 169 } 170 } 171 } 172 else { 173 ++*num_lookup_with_key; 174 ++*stats().map_lookups; 175 auto decls = specialFunctionTable[kind]->find(otypeKey); 176 if (decls == specialFunctionTable[kind]->end()) return {}; 177 178 for (auto decl : *(decls->second)) { 179 out.push_back(decl.second); 180 } 181 } 182 183 ++*stat_counts[kind]; 184 *stat_candidates[kind] += out.size(); 185 109 186 return out; 110 187 } … … 313 390 if ( ! expr->result ) continue; 314 391 const Type * resTy = expr->result->stripReferences(); 315 auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );392 auto aggrType = dynamic_cast< const BaseInstType * >( resTy ); 316 393 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 317 394 toString( expr->result ).c_str() ); … … 335 412 } 336 413 337 void SymbolTable::addFunctionType( const FunctionType * ftype ) { 338 addTypes( ftype->forall ); 339 addIds( ftype->returns ); 340 addIds( ftype->params ); 341 } 414 415 void SymbolTable::addFunction( const FunctionDecl * func ) { 416 for (auto & td : func->type_params) { 417 addType(td); 418 } 419 for (auto & asst : func->assertions) { 420 addId(asst); 421 } 422 // addTypes( func->type->forall ); 423 addIds( func->returns ); 424 addIds( func->params ); 425 } 426 342 427 343 428 void SymbolTable::lazyInitScope() { … … 364 449 namespace { 365 450 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 366 std::string getOtypeKey( const Function Decl * function) {367 const auto & params = f unction->type->params;451 std::string getOtypeKey( const FunctionType * ftype, bool stripParams = true ) { 452 const auto & params = ftype->params; 368 453 assert( ! params.empty() ); 369 454 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 370 const Type * base = InitTweak::getPointerBase( params.front() ->get_type());455 const Type * base = InitTweak::getPointerBase( params.front() ); 371 456 assert( base ); 372 return Mangle::mangle( base ); 457 if (stripParams) { 458 if (dynamic_cast<const PointerType *>(base)) return Mangle::Encoding::pointer; 459 return Mangle::mangle( base, Mangle::Type | Mangle::NoGenericParams ); 460 } 461 else 462 return Mangle::mangle( base ); 373 463 } 374 464 … … 378 468 const DeclWithType * decl, const std::string & otypeKey ) { 379 469 auto func = dynamic_cast< const FunctionDecl * >( decl ); 380 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;470 if ( ! func || otypeKey != getOtypeKey( func->type, false ) ) return nullptr; 381 471 return func; 382 472 } … … 403 493 bool dataIsUserDefinedFunc = ! function->linkage.is_overrideable; 404 494 bool dataIsCopyFunc = InitTweak::isCopyFunction( function ); 405 std::string dataOtypeKey = getOtypeKey( function );495 std::string dataOtypeKey = getOtypeKey( function->type, false ); // requires exact match to override autogen 406 496 407 497 if ( dataIsUserDefinedFunc && dataIsCopyFunc ) { … … 575 665 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 666 const Decl * deleter ) { 667 SpecialFunctionKind kind = getSpecialFunctionKind(decl->name); 668 if (kind == NUMBER_OF_KINDS) { // not a special decl 669 addId(decl, decl->name, idTable, handleConflicts, baseExpr, deleter); 670 } 671 else { 672 std::string key; 673 if (auto func = dynamic_cast<const FunctionDecl *>(decl)) { 674 key = getOtypeKey(func->type); 675 } 676 else if (auto obj = dynamic_cast<const ObjectDecl *>(decl)) { 677 key = getOtypeKey(obj->type.strict_as<PointerType>()->base.strict_as<FunctionType>()); 678 } 679 else { 680 assertf(false, "special decl with non-function type"); 681 } 682 addId(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter); 683 } 684 } 685 686 void SymbolTable::addId( 687 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 688 const Decl * deleter ) { 577 689 ++*stats().add_calls; 578 690 const std::string &name = decl->name; … … 605 717 // ensure tables exist and add identifier 606 718 MangleTable::Ptr mangleTable; 607 if ( ! idTable ) {608 idTable = IdTable::new_ptr();719 if ( ! table ) { 720 table = IdTable::new_ptr(); 609 721 mangleTable = MangleTable::new_ptr(); 610 722 } else { 611 723 ++*stats().map_lookups; 612 auto decls = idTable->find( name);613 if ( decls == idTable->end() ) {724 auto decls = table->find( lookupKey ); 725 if ( decls == table->end() ) { 614 726 mangleTable = MangleTable::new_ptr(); 615 727 } else { … … 626 738 lazyInitScope(); 627 739 *stats().map_mutations += 2; 628 idTable = idTable->set(629 name,740 table = table->set( 741 lookupKey, 630 742 mangleTable->set( 631 743 mangleName, … … 642 754 IdData data{ decl, baseExpr, deleter, scope }; 643 755 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 644 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 756 if (table != idTable) { // adding to special table 757 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 758 } 645 759 *stats().map_mutations += 2; 646 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );760 table = table->set( lookupKey, mangleTable->set( mangleName, std::move(data) ) ); 647 761 } 648 762 … … 654 768 if ( dwt->name == "" ) { 655 769 const Type * t = dwt->get_type()->stripReferences(); 656 if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {770 if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) { 657 771 if ( ! dynamic_cast<const StructInstType *>(rty) 658 772 && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
Note:
See TracChangeset
for help on using the changeset viewer.