Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r0522ebe r2beaf9b  
    891891                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    892892                        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                        }
    951907                }
    952908        }
     
    1018974                                        }
    1019975
    1020                                         if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);                                             
     976                                        if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);
    1021977                                        else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type));
    1022978                                }
     
    12831239                                                restructureCast( cand->expr, toType, castExpr->isGenerated ),
    12841240                                                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.
    12861242                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
    12871243                                        // we may need to revisit the logic.
     
    14441400        }
    14451401
    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        }
    15121406
    15131407        void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
     
    16181512        void Finder::postvisit( const ast::ConditionalExpr * conditionalExpr ) {
    16191513                // candidates for condition
     1514                ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 );
    16201515                CandidateFinder finder1( context, tenv );
    1621                 ast::ptr<ast::Expr> arg1 = notZeroExpr( conditionalExpr->arg1 );
    16221516                finder1.find( arg1, ResolveMode::withAdjustment() );
    16231517                if ( finder1.candidates.empty() ) return;
    16241518
    16251519                // 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();
    16261523                CandidateFinder finder2( context, tenv );
    16271524                finder2.allowVoid = true;
    1628                 finder2.find( conditionalExpr->arg2, ResolveMode::withAdjustment() );
     1525                finder2.find( arg2, ResolveMode::withAdjustment() );
    16291526                if ( finder2.candidates.empty() ) return;
    16301527
     
    18971794                                        CandidateRef newCand =
    18981795                                                std::make_shared<Candidate>(
    1899                                                         newExpr, copy( tenv ), ast::OpenVarSet{}, 
     1796                                                        newExpr, copy( tenv ), ast::OpenVarSet{},
    19001797                                                        ast::AssertionSet{}, Cost::zero, cost
    19011798                                                );
    1902                                        
     1799
    19031800                                        if (newCand->expr->env) {
    19041801                                                newCand->env.add(*newCand->expr->env);
Note: See TracChangeset for help on using the changeset viewer.