Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/SymbolTable.cpp

    re5c3811 r490fb92e  
    9595}
    9696
    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 
    10497std::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 
    11298        ++*stats().lookup_calls;
    11399        if ( ! idTable ) return {};
     
    121107                out.push_back( decl.second );
    122108        }
    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 
    186109        return out;
    187110}
     
    443366namespace {
    444367        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
    445         std::string getOtypeKey( const FunctionType * ftype, bool stripParams = true ) {
    446                 const auto & params = ftype->params;
     368        std::string getOtypeKey( const FunctionDecl * function ) {
     369                const auto & params = function->type->params;
    447370                assert( ! params.empty() );
    448371                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    449372                const Type * base = InitTweak::getPointerBase( params.front() );
    450373                assert( base );
    451                 if (stripParams) {
    452                         if (dynamic_cast<const PointerType *>(base)) return Mangle::Encoding::pointer;
    453                         return Mangle::mangle( base, Mangle::Type | Mangle::NoGenericParams );
    454                 }
    455                 else
    456                         return Mangle::mangle( base ); 
     374                return Mangle::mangle( base );
    457375        }
    458376
     
    462380                        const DeclWithType * decl, const std::string & otypeKey ) {
    463381                auto func = dynamic_cast< const FunctionDecl * >( decl );
    464                 if ( ! func || otypeKey != getOtypeKey( func->type, false ) ) return nullptr;
     382                if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
    465383                return func;
    466384        }
     
    487405        bool dataIsUserDefinedFunc = ! function->linkage.is_overrideable;
    488406        bool dataIsCopyFunc = InitTweak::isCopyFunction( function );
    489         std::string dataOtypeKey = getOtypeKey( function->type, false ); // requires exact match to override autogen
     407        std::string dataOtypeKey = getOtypeKey( function );
    490408
    491409        if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
     
    659577                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    660578                const Decl * deleter ) {
    661         SpecialFunctionKind kind = getSpecialFunctionKind(decl->name);
    662         if (kind == NUMBER_OF_KINDS) { // not a special decl
    663                 addId(decl, decl->name, idTable, handleConflicts, baseExpr, deleter);
    664         }
    665         else {
    666                 std::string key;
    667                 if (auto func = dynamic_cast<const FunctionDecl *>(decl)) {
    668                         key = getOtypeKey(func->type);
    669                 }
    670                 else if (auto obj = dynamic_cast<const ObjectDecl *>(decl)) {
    671                         key = getOtypeKey(obj->type.strict_as<PointerType>()->base.strict_as<FunctionType>());
    672                 }
    673                 else {
    674                         assertf(false, "special decl with non-function type");
    675                 }
    676                 addId(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter);
    677         }
    678 }
    679 
    680 void SymbolTable::addId(
    681                 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    682                 const Decl * deleter ) {
    683579        ++*stats().add_calls;
    684580        const std::string &name = decl->name;
     
    711607        // ensure tables exist and add identifier
    712608        MangleTable::Ptr mangleTable;
    713         if ( ! table ) {
    714                 table = IdTable::new_ptr();
     609        if ( ! idTable ) {
     610                idTable = IdTable::new_ptr();
    715611                mangleTable = MangleTable::new_ptr();
    716612        } else {
    717613                ++*stats().map_lookups;
    718                 auto decls = table->find( lookupKey );
    719                 if ( decls == table->end() ) {
     614                auto decls = idTable->find( name );
     615                if ( decls == idTable->end() ) {
    720616                        mangleTable = MangleTable::new_ptr();
    721617                } else {
     
    732628                                                lazyInitScope();
    733629                                                *stats().map_mutations += 2;
    734                                                 table = table->set(
    735                                                         lookupKey,
     630                                                idTable = idTable->set(
     631                                                        name,
    736632                                                        mangleTable->set(
    737633                                                                mangleName,
     
    748644        IdData data{ decl, baseExpr, deleter, scope };
    749645        // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
    750         if (table != idTable) { // adding to special table
    751                 if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    752         }
     646        if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    753647        *stats().map_mutations += 2;
    754         table = table->set( lookupKey, mangleTable->set( mangleName, std::move(data) ) );
     648        idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
    755649}
    756650
Note: See TracChangeset for help on using the changeset viewer.