Changes in / [b3ed43a3:04994aa]


Ignore:
Files:
9 added
26 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel.cfa

    rb3ed43a3 r04994aa  
    379379
    380380        ready_schedule_lock();
    381                 // Dereference the thread now because once we push it, there is not guaranteed it's still valid.
    382                 struct cluster * cl = thrd->curr_cluster;
    383 
    384                 // push the thread to the cluster ready-queue
    385                 push( cl, thrd );
    386 
    387                 // variable thrd is no longer safe to use
    388 
    389                 // wake the cluster using the save variable.
    390                 __wake_one( cl );
     381                push( thrd->curr_cluster, thrd );
     382                __wake_one(thrd->curr_cluster);
    391383        ready_schedule_unlock();
    392384
  • src/AST/Expr.hpp

    rb3ed43a3 r04994aa  
    299299};
    300300
    301 /// Inidicates whether the cast is introduced by the CFA type system.
    302 /// GeneratedCast for casts that the resolver introduces to force a return type
    303 /// ExplicitCast for casts from user code
    304 /// ExplicitCast for casts from desugaring advanced CFA features into simpler CFA
    305 /// example
    306 ///   int * p;     // declaration
    307 ///   (float *) p; // use, with subject cast
    308 /// subject cast being GeneratedCast means we are considering an interpretation with a type mismatch
    309 /// subject cast being ExplicitCast means someone in charge wants it that way
     301/// Whether a cast existed in the program source or not
    310302enum GeneratedFlag { ExplicitCast, GeneratedCast };
    311303
  • src/AST/SymbolTable.cpp

    rb3ed43a3 r04994aa  
    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
  • src/AST/SymbolTable.hpp

    rb3ed43a3 r04994aa  
    3333class SymbolTable final : public std::enable_shared_from_this<ast::SymbolTable> {
    3434public:
    35         /// special functions stored in dedicated tables, with different lookup keys
    36         enum SpecialFunctionKind {CTOR, DTOR, ASSIGN, NUMBER_OF_KINDS};
    37         static SpecialFunctionKind getSpecialFunctionKind(const std::string & name);
    38 
    3935        /// Stored information about a declaration
    4036        struct IdData {
     
    8177        UnionTable::Ptr unionTable;    ///< union namespace
    8278        TraitTable::Ptr traitTable;    ///< trait namespace
    83         IdTable::Ptr specialFunctionTable[NUMBER_OF_KINDS];
    84 
    85         // using SpecialFuncTable = PersistentMap< std::string, IdTable::Ptr >; // fname (ctor/dtor/assign) - otypekey
    86         // SpecialFuncTable::Ptr specialFuncTable;
    8779
    8880        using Ptr = std::shared_ptr<const SymbolTable>;
     
    10395        /// Gets all declarations with the given ID
    10496        std::vector<IdData> lookupId( const std::string &id ) const;
    105         /// Gets special functions associated with a type; if no key is given, returns everything
    106         std::vector<IdData> specialLookupId( SpecialFunctionKind kind, const std::string & otypeKey = "" ) const;
    10797        /// Gets the top-most type declaration with the given ID
    10898        const NamedTypeDecl * lookupType( const std::string &id ) const;
     
    196186                const Decl * deleter = nullptr );
    197187
    198         /// common code for addId when special decls are placed into separate tables
    199         void addId(
    200                 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & idTable, OnConflict handleConflicts,
    201                 const Expr * baseExpr = nullptr, const Decl * deleter = nullptr);
    202        
    203188        /// adds all of the members of the Aggregate (addWith helper)
    204189        void addMembers( const AggregateDecl * aggr, const Expr * expr, OnConflict handleConflicts );
  • src/AST/Type.cpp

    rb3ed43a3 r04994aa  
    216216}
    217217
    218 bool isUnboundType(const Type * type) {
    219         if (auto typeInst = dynamic_cast<const TypeInstType *>(type)) {
    220                 // xxx - look for a type name produced by renameTyVars.
    221 
    222                 // TODO: once TypeInstType representation is updated, it should properly check
    223                 // if the context id is filled. this is a temporary hack for now
    224                 if (std::count(typeInst->name.begin(), typeInst->name.end(), '_') >= 3) {
    225                         return true;
    226                 }
    227         }
    228         return false;
    229 }
    230 
    231218}
    232219
  • src/AST/Type.hpp

    rb3ed43a3 r04994aa  
    535535};
    536536
    537 bool isUnboundType(const Type * type);
    538 
    539537}
    540538
  • src/InitTweak/FixInit.h

    rb3ed43a3 r04994aa  
    2121class Declaration;
    2222namespace ast {
    23         struct TranslationUnit;
     23        class TranslationUnit;
    2424}
    2525
  • src/Parser/ParseNode.h

    rb3ed43a3 r04994aa  
    3737class Attribute;
    3838class Declaration;
    39 struct DeclarationNode;
     39class DeclarationNode;
    4040class DeclarationWithType;
    4141class ExpressionNode;
    4242class Initializer;
    43 struct StatementNode;
     43class StatementNode;
    4444
    4545//##############################################################################
  • src/ResolvExpr/CandidateFinder.cpp

    rb3ed43a3 r04994aa  
    4343#include "SymTab/Validate.h"      // for validateType
    4444#include "Tuples/Tuples.h"        // for handleTupleAssignment
    45 #include "InitTweak/InitTweak.h"  // for getPointerBase
    46 
    47 #include "Common/Stats/Counter.h"
    4845
    4946#define PRINT( text ) if ( resolvep ) { text }
     
    867864
    868865                void postvisit( const ast::UntypedExpr * untypedExpr ) {
     866                        CandidateFinder funcFinder{ symtab, tenv };
     867                        funcFinder.find( untypedExpr->func, ResolvMode::withAdjustment() );
     868                        // short-circuit if no candidates
     869                        if ( funcFinder.candidates.empty() ) return;
     870
     871                        reason.code = NoMatch;
     872
    869873                        std::vector< CandidateFinder > argCandidates =
    870874                                selfFinder.findSubExprs( untypedExpr->args );
     
    873877                        // if not tuple assignment, handled as normal function call
    874878                        Tuples::handleTupleAssignment( selfFinder, untypedExpr, argCandidates );
    875 
    876                         CandidateFinder funcFinder{ symtab, tenv };
    877                         if (auto nameExpr = untypedExpr->func.as<ast::NameExpr>()) {
    878                                 auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
    879                                 if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
    880                                         assertf(!argCandidates.empty(), "special function call without argument");
    881                                         for (auto & firstArgCand: argCandidates[0]) {
    882                                                 ast::ptr<ast::Type> argType = firstArgCand->expr->result;
    883                                                 firstArgCand->env.apply(argType);
    884                                                 // strip references
    885                                                 // xxx - is this correct?
    886                                                 while (argType.as<ast::ReferenceType>()) argType = argType.as<ast::ReferenceType>()->base;
    887 
    888                                                 // convert 1-tuple to plain type
    889                                                 if (auto tuple = argType.as<ast::TupleType>()) {
    890                                                         if (tuple->size() == 1) {
    891                                                                 argType = tuple->types[0];
    892                                                         }
    893                                                 }
    894                                                
    895                                                 // if argType is an unbound type parameter, all special functions need to be searched.
    896                                                 if (isUnboundType(argType)) {
    897                                                         funcFinder.otypeKeys.clear();
    898                                                         break;
    899                                                 }
    900 
    901                                                 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);
    902                                                 else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type));
    903                                         }
    904                                 }
    905                         }
    906                         // if candidates are already produced, do not fail
    907                         // xxx - is it possible that handleTupleAssignment and main finder both produce candidates?
    908                         // this means there exists ctor/assign functions with a tuple as first parameter.
    909                         funcFinder.find( untypedExpr->func, selfFinder.candidates.empty() ? ResolvMode::withAdjustment() : ResolvMode::withoutFailFast() );
    910                         // short-circuit if no candidates
    911                         // if ( funcFinder.candidates.empty() ) return;
    912 
    913                         reason.code = NoMatch;
    914879
    915880                        // find function operators
     
    11011066                                // unification run for side-effects
    11021067                                unify( toType, cand->expr->result, cand->env, need, have, open, symtab );
    1103                                 Cost thisCost =
    1104                                         (castExpr->isGenerated == ast::GeneratedFlag::GeneratedCast)
    1105                             ? conversionCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env )
    1106                             : castCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env );
    1107 
     1068                                Cost thisCost = castCost( cand->expr->result, toType, cand->expr->get_lvalue(),
     1069                                                symtab, cand->env );
    11081070                                PRINT(
    11091071                                        std::cerr << "working on cast with result: " << toType << std::endl;
     
    12251187
    12261188                void postvisit( const ast::NameExpr * nameExpr ) {
    1227                         std::vector< ast::SymbolTable::IdData > declList;
    1228                         if (!selfFinder.otypeKeys.empty()) {
    1229                                 auto kind = ast::SymbolTable::getSpecialFunctionKind(nameExpr->name);
    1230                                 assertf(kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS, "special lookup with non-special target: %s", nameExpr->name.c_str());
    1231 
    1232                                 for (auto & otypeKey: selfFinder.otypeKeys) {
    1233                                         auto result = symtab.specialLookupId(kind, otypeKey);
    1234                                         declList.insert(declList.end(), std::make_move_iterator(result.begin()), std::make_move_iterator(result.end()));
    1235                                 }
    1236                         }
    1237                         else {
    1238                                 declList = symtab.lookupId( nameExpr->name );
    1239                         }
     1189                        std::vector< ast::SymbolTable::IdData > declList = symtab.lookupId( nameExpr->name );
    12401190                        PRINT( std::cerr << "nameExpr is " << nameExpr->name << std::endl; )
    1241 
    12421191                        if( declList.empty() ) return;
    12431192
     
    15941543
    15951544                                        // unification run for side-effects
    1596                                         bool canUnify = unify( toType, cand->expr->result, env, need, have, open, symtab );
    1597                                         (void) canUnify;
     1545                                        unify( toType, cand->expr->result, env, need, have, open, symtab );
    15981546                                        Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    1599                                                 symtab, env );
    1600                                         PRINT(
    1601                                                 Cost legacyCost = castCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    16021547                                                        symtab, env );
    1603                                                 std::cerr << "Considering initialization:";
    1604                                                 std::cerr << std::endl << "  FROM: " << cand->expr->result << std::endl;
    1605                                                 std::cerr << std::endl << "  TO: "   << toType             << std::endl;
    1606                                                 std::cerr << std::endl << "  Unification " << (canUnify ? "succeeded" : "failed");
    1607                                                 std::cerr << std::endl << "  Legacy cost " << legacyCost;
    1608                                                 std::cerr << std::endl << "  New cost " << thisCost;
    1609                                                 std::cerr << std::endl;
    1610                                         )
     1548
    16111549                                        if ( thisCost != Cost::infinity ) {
    16121550                                                // count one safe conversion for each value that is thrown away
     
    16201558                                        }
    16211559                                }
    1622 
    16231560                        }
    16241561
  • src/ResolvExpr/CandidateFinder.hpp

    rb3ed43a3 r04994aa  
    3131        const ast::TypeEnvironment & env;  ///< Substitutions performed in this resolution
    3232        ast::ptr< ast::Type > targetType;  ///< Target type for resolution
    33         std::set< std::string > otypeKeys;  /// different type may map to same key
    3433
    3534        CandidateFinder(
  • src/ResolvExpr/Resolver.h

    rb3ed43a3 r04994aa  
    3535        class StmtExpr;
    3636        class SymbolTable;
    37         struct TranslationUnit;
     37        class TranslationUnit;
    3838        class Type;
    3939        class TypeEnvironment;
     
    6363        ast::ptr< ast::Expr > resolveInVoidContext(
    6464                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env );
    65         /// Resolve `untyped` to the single expression whose candidate is the best match for the
     65        /// Resolve `untyped` to the single expression whose candidate is the best match for the 
    6666        /// given type.
    6767        ast::ptr< ast::Expr > findSingleExpression(
  • src/ResolvExpr/SatisfyAssertions.cpp

    rb3ed43a3 r04994aa  
    167167                // find candidates that unify with the desired type
    168168                AssnCandidateList matches;
    169 
    170                 std::vector<ast::SymbolTable::IdData> candidates;
    171                 auto kind = ast::SymbolTable::getSpecialFunctionKind(assn.first->name);
    172                 if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
    173                         // prefilter special decls by argument type, if already known
    174                         ast::ptr<ast::Type> thisArgType = strict_dynamic_cast<const ast::PointerType *>(assn.first->get_type())->base
    175                                 .strict_as<ast::FunctionType>()->params[0]
    176                                 .strict_as<ast::ReferenceType>()->base;
    177                         sat.cand->env.apply(thisArgType);
    178 
    179                         std::string otypeKey = "";
    180                         if (thisArgType.as<ast::PointerType>()) otypeKey = Mangle::Encoding::pointer;
    181                         else if (!isUnboundType(thisArgType)) otypeKey = Mangle::mangle(thisArgType, Mangle::Type | Mangle::NoGenericParams);
    182 
    183                         candidates = sat.symtab.specialLookupId(kind, otypeKey);
    184                 }
    185                 else {
    186                         candidates = sat.symtab.lookupId(assn.first->name);
    187                 }
    188                 for ( const ast::SymbolTable::IdData & cdata : candidates ) {
     169                for ( const ast::SymbolTable::IdData & cdata : sat.symtab.lookupId( assn.first->name ) ) {
    189170                        const ast::DeclWithType * candidate = cdata.id;
    190171
Note: See TracChangeset for help on using the changeset viewer.