- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CandidateFinder.cpp
r0522ebe r2beaf9b 891 891 } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) { 892 892 addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" ); 893 } 894 else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) { 895 if (enumInst->base && enumInst->base->base) { 896 const CodeLocation &location = cand->expr->location; 897 898 CandidateFinder funcFinder(context, tenv); 899 auto nameExpr = new ast::NameExpr(location, "valueE"); 900 ResolveMode mode = {true, false, selfFinder.candidates.empty()}; 901 funcFinder.find( nameExpr, mode ); 902 903 // make variableExpr itself the candidate for the value Call 904 ExplodedArgs argExpansions; 905 argExpansions.emplace_back(); 906 auto &argE = argExpansions.back(); 907 908 argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value 909 910 CandidateList found; 911 SemanticErrorException errors; 912 913 for (CandidateRef &func : funcFinder) { 914 try { 915 const ast::Type *funcResult = 916 func->expr->result->stripReferences(); 917 if (auto pointer = dynamic_cast<const ast::PointerType *>( 918 funcResult)) { 919 if (auto function = 920 pointer->base.as<ast::FunctionType>()) { 921 CandidateRef newFunc{new Candidate{*func}}; 922 newFunc->expr = referenceToRvalueConversion( 923 newFunc->expr, newFunc->cost); 924 makeFunctionCandidates( location, 925 newFunc, function, 926 argExpansions, found ); 927 } 928 } 929 } catch (SemanticErrorException &e) { 930 std::cerr 931 << "Resolving value function should cause an error" 932 << std::endl; 933 errors.append(e); 934 } 935 } 936 937 if (found.empty()) { 938 std::cerr << "Resolve value function should always success" 939 << std::endl; 940 } 941 942 for (CandidateRef &withFunc : found) { 943 withFunc->cost.incSafe(); 944 Cost cvtCost = 945 computeApplicationConversionCost(withFunc, symtab); 946 assert(cvtCost != Cost::infinity); 947 948 candidates.emplace_back(std::move(withFunc)); 949 } 950 } 893 } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) { 894 // The Attribute Arrays are not yet generated, need to proxy them 895 // as attribute function call 896 const CodeLocation & location = cand->expr->location; 897 if ( enumInst->base && enumInst->base->base ) { 898 auto valueName = new ast::NameExpr(location, "valueE"); 899 auto untypedValueCall = new ast::UntypedExpr( 900 location, valueName, { aggrExpr } ); 901 auto result = ResolvExpr::findVoidExpression( untypedValueCall, context ); 902 assert( result.get() ); 903 CandidateRef newCand = std::make_shared<Candidate>( 904 *cand, result, Cost::safe ); 905 candidates.emplace_back( std::move( newCand ) ); 906 } 951 907 } 952 908 } … … 1018 974 } 1019 975 1020 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 976 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 1021 977 else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type)); 1022 978 } … … 1283 1239 restructureCast( cand->expr, toType, castExpr->isGenerated ), 1284 1240 copy( cand->env ), std::move( open ), std::move( need ), cand->cost + thisCost); 1285 // currently assertions are always resolved immediately so this should have no effect. 1241 // currently assertions are always resolved immediately so this should have no effect. 1286 1242 // if this somehow changes in the future (e.g. delayed by indeterminate return type) 1287 1243 // we may need to revisit the logic. … … 1444 1400 } 1445 1401 1446 void Finder::postvisit(const ast::VariableExpr *variableExpr) { 1447 // not sufficient to just pass `variableExpr` here, type might have changed 1448 1449 auto cand = new Candidate(variableExpr, tenv); 1450 candidates.emplace_back(cand); 1451 1452 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>( 1453 variableExpr->var->get_type())) { 1454 if (enumInst->base && enumInst->base->base) { 1455 const CodeLocation &location = cand->expr->location; 1456 1457 CandidateFinder funcFinder(context, tenv); 1458 auto nameExpr = new ast::NameExpr(location, "valueE"); 1459 ResolveMode mode = {true, false, selfFinder.candidates.empty()}; 1460 funcFinder.find( nameExpr, mode ); 1461 1462 // make variableExpr itself the candidate for the value Call 1463 ExplodedArgs argExpansions; 1464 argExpansions.emplace_back(); 1465 auto &argE = argExpansions.back(); 1466 1467 argE.emplace_back(*cand, symtab); 1468 1469 CandidateList found; 1470 SemanticErrorException errors; 1471 1472 for (CandidateRef &func : funcFinder) { 1473 try { 1474 const ast::Type *funcResult = 1475 func->expr->result->stripReferences(); 1476 if (auto pointer = dynamic_cast<const ast::PointerType *>( 1477 funcResult)) { 1478 if (auto function = 1479 pointer->base.as<ast::FunctionType>()) { 1480 CandidateRef newFunc{new Candidate{*func}}; 1481 newFunc->expr = referenceToRvalueConversion( 1482 newFunc->expr, newFunc->cost); 1483 makeFunctionCandidates(variableExpr->location, 1484 newFunc, function, 1485 argExpansions, found); 1486 } 1487 } 1488 } catch (SemanticErrorException &e) { 1489 std::cerr 1490 << "Resolving value function should cause an error" 1491 << std::endl; 1492 errors.append(e); 1493 } 1494 } 1495 1496 if (found.empty()) { 1497 std::cerr << "Resolve value function should always success" 1498 << std::endl; 1499 } 1500 1501 for (CandidateRef &withFunc : found) { 1502 withFunc->cost.incSafe(); 1503 Cost cvtCost = 1504 computeApplicationConversionCost(withFunc, symtab); 1505 assert(cvtCost != Cost::infinity); 1506 1507 candidates.emplace_back(std::move(withFunc)); 1508 } 1509 } 1510 } 1511 } 1402 void Finder::postvisit( const ast::VariableExpr * variableExpr ) { 1403 // not sufficient to just pass `variableExpr` here, type might have changed since 1404 addCandidate( variableExpr, tenv ); 1405 } 1512 1406 1513 1407 void Finder::postvisit( const ast::ConstantExpr * constantExpr ) { … … 1618 1512 void Finder::postvisit( const ast::ConditionalExpr * conditionalExpr ) { 1619 1513 // candidates for condition 1514 ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 ); 1620 1515 CandidateFinder finder1( context, tenv ); 1621 ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 );1622 1516 finder1.find( arg1, ResolveMode::withAdjustment() ); 1623 1517 if ( finder1.candidates.empty() ) return; 1624 1518 1625 1519 // candidates for true result 1520 // FIX ME: resolves and runs arg1 twice when arg2 is missing. 1521 ast::Expr const * arg2 = conditionalExpr->arg2; 1522 arg2 = arg2 ? arg2 : conditionalExpr->arg1.get(); 1626 1523 CandidateFinder finder2( context, tenv ); 1627 1524 finder2.allowVoid = true; 1628 finder2.find( conditionalExpr->arg2, ResolveMode::withAdjustment() );1525 finder2.find( arg2, ResolveMode::withAdjustment() ); 1629 1526 if ( finder2.candidates.empty() ) return; 1630 1527 … … 1897 1794 CandidateRef newCand = 1898 1795 std::make_shared<Candidate>( 1899 newExpr, copy( tenv ), ast::OpenVarSet{}, 1796 newExpr, copy( tenv ), ast::OpenVarSet{}, 1900 1797 ast::AssertionSet{}, Cost::zero, cost 1901 1798 ); 1902 1799 1903 1800 if (newCand->expr->env) { 1904 1801 newCand->env.add(*newCand->expr->env);
Note: See TracChangeset
for help on using the changeset viewer.