Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/SymbolTable.cpp

    r3e5dd913 re67991f  
    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}
     
    390313                if ( ! expr->result ) continue;
    391314                const Type * resTy = expr->result->stripReferences();
    392                 auto aggrType = dynamic_cast< const BaseInstType * >( resTy );
     315                auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
    393316                assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
    394317                        toString( expr->result ).c_str() );
     
    412335}
    413336
    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 
     337void SymbolTable::addFunctionType( const FunctionType * ftype ) {
     338        addTypes( ftype->forall );
     339        addIds( ftype->returns );
     340        addIds( ftype->params );
     341}
    427342
    428343void SymbolTable::lazyInitScope() {
     
    449364namespace {
    450365        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
    451         std::string getOtypeKey( const FunctionType * ftype, bool stripParams = true ) {
    452                 const auto & params = ftype->params;
     366        std::string getOtypeKey( const FunctionDecl * function ) {
     367                const auto & params = function->type->params;
    453368                assert( ! params.empty() );
    454369                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    455                 const Type * base = InitTweak::getPointerBase( params.front() );
     370                const Type * base = InitTweak::getPointerBase( params.front()->get_type() );
    456371                assert( 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 ); 
     372                return Mangle::mangle( base );
    463373        }
    464374
     
    468378                        const DeclWithType * decl, const std::string & otypeKey ) {
    469379                auto func = dynamic_cast< const FunctionDecl * >( decl );
    470                 if ( ! func || otypeKey != getOtypeKey( func->type, false ) ) return nullptr;
     380                if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
    471381                return func;
    472382        }
     
    493403        bool dataIsUserDefinedFunc = ! function->linkage.is_overrideable;
    494404        bool dataIsCopyFunc = InitTweak::isCopyFunction( function );
    495         std::string dataOtypeKey = getOtypeKey( function->type, false ); // requires exact match to override autogen
     405        std::string dataOtypeKey = getOtypeKey( function );
    496406
    497407        if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
     
    665575                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    666576                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 ) {
    689577        ++*stats().add_calls;
    690578        const std::string &name = decl->name;
     
    717605        // ensure tables exist and add identifier
    718606        MangleTable::Ptr mangleTable;
    719         if ( ! table ) {
    720                 table = IdTable::new_ptr();
     607        if ( ! idTable ) {
     608                idTable = IdTable::new_ptr();
    721609                mangleTable = MangleTable::new_ptr();
    722610        } else {
    723611                ++*stats().map_lookups;
    724                 auto decls = table->find( lookupKey );
    725                 if ( decls == table->end() ) {
     612                auto decls = idTable->find( name );
     613                if ( decls == idTable->end() ) {
    726614                        mangleTable = MangleTable::new_ptr();
    727615                } else {
     
    738626                                                lazyInitScope();
    739627                                                *stats().map_mutations += 2;
    740                                                 table = table->set(
    741                                                         lookupKey,
     628                                                idTable = idTable->set(
     629                                                        name,
    742630                                                        mangleTable->set(
    743631                                                                mangleName,
     
    754642        IdData data{ decl, baseExpr, deleter, scope };
    755643        // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
    756         if (table != idTable) { // adding to special table
    757                 if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    758         }
     644        if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    759645        *stats().map_mutations += 2;
    760         table = table->set( lookupKey, mangleTable->set( mangleName, std::move(data) ) );
     646        idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
    761647}
    762648
     
    768654                        if ( dwt->name == "" ) {
    769655                                const Type * t = dwt->get_type()->stripReferences();
    770                                 if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) {
     656                                if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {
    771657                                        if ( ! dynamic_cast<const StructInstType *>(rty)
    772658                                                && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
Note: See TracChangeset for help on using the changeset viewer.