- File:
-
- 1 edited
-
src/ResolvExpr/CandidateFinder.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CandidateFinder.cpp
r0292aa4 r954c954 43 43 #include "SymTab/Validate.h" // for validateType 44 44 #include "Tuples/Tuples.h" // for handleTupleAssignment 45 #include "InitTweak/InitTweak.h" // for getPointerBase46 47 #include "Common/Stats/Counter.h"48 45 49 46 #define PRINT( text ) if ( resolvep ) { text } … … 867 864 868 865 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 869 873 std::vector< CandidateFinder > argCandidates = 870 874 selfFinder.findSubExprs( untypedExpr->args ); … … 873 877 // if not tuple assignment, handled as normal function call 874 878 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 references885 // xxx - is this correct?886 while (argType.as<ast::ReferenceType>()) argType = argType.as<ast::ReferenceType>()->base;887 888 // convert 1-tuple to plain type889 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 fail907 // 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 candidates911 // if ( funcFinder.candidates.empty() ) return;912 913 reason.code = NoMatch;914 879 915 880 // find function operators … … 1101 1066 // unification run for side-effects 1102 1067 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 ); 1108 1070 PRINT( 1109 1071 std::cerr << "working on cast with result: " << toType << std::endl; … … 1225 1187 1226 1188 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 ); 1240 1190 PRINT( std::cerr << "nameExpr is " << nameExpr->name << std::endl; ) 1241 1242 1191 if( declList.empty() ) return; 1243 1192 … … 1594 1543 1595 1544 // 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 ); 1598 1546 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(),1602 1547 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 1611 1549 if ( thisCost != Cost::infinity ) { 1612 1550 // count one safe conversion for each value that is thrown away … … 1620 1558 } 1621 1559 } 1622 1623 1560 } 1624 1561
Note:
See TracChangeset
for help on using the changeset viewer.