Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r0292aa4 r954c954  
    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
Note: See TracChangeset for help on using the changeset viewer.