Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r4b7cce6 r60aaa51d  
    3535#include "AST/Print.hpp"
    3636#include "AST/SymbolTable.hpp"
    37 #include "AST/Type.hpp"
    3837#include "Common/PassVisitor.h"          // for PassVisitor
    3938#include "Common/SemanticError.h"        // for SemanticError
     
    957956                        }
    958957                };
    959         } // anonymous namespace
    960 
    961         /// Check if this expression is or includes a deleted expression
    962         const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
    963                 ast::Pass<DeleteFinder_new> finder;
    964                 expr->accept( finder );
    965                 return finder.pass.delExpr;
    966         }
    967 
    968         namespace {
     958
     959                /// Check if this expression is or includes a deleted expression
     960                const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
     961                        ast::Pass<DeleteFinder_new> finder;
     962                        expr->accept( finder );
     963                        return finder.pass.delExpr;
     964                }
     965
    969966                /// always-accept candidate filter
    970967                bool anyCandidate( const Candidate & ) { return true; }
     
    10261023
    10271024                        // promote candidate.cvtCost to .cost
    1028                         promoteCvtCost( winners );
     1025                        for ( CandidateRef & cand : winners ) {
     1026                                cand->cost = cand->cvtCost;
     1027                        }
    10291028
    10301029                        // produce ambiguous errors, if applicable
     
    11001099                        StripCasts_new::strip( expr );
    11011100                }
    1102         } // anonymous namespace
    1103 
    1104                
    1105         ast::ptr< ast::Expr > resolveInVoidContext(
    1106                 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
    1107         ) {
    1108                 assertf( expr, "expected a non-null expression" );
    1109                
    1110                 // set up and resolve expression cast to void
    1111                 ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr };
    1112                 CandidateRef choice = findUnfinishedKindExpression(
    1113                         untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
    1114                
    1115                 // a cast expression has either 0 or 1 interpretations (by language rules);
    1116                 // if 0, an exception has already been thrown, and this code will not run
    1117                 const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >();
    1118                 env = std::move( choice->env );
    1119 
    1120                 return castExpr->arg;
    1121         }
    1122 
    1123         namespace {
     1101
     1102                /// Find the expression candidate that is the unique best match for `untyped` in a `void`
     1103                /// context.
     1104                ast::ptr< ast::Expr > resolveInVoidContext(
     1105                        const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
     1106                ) {
     1107                        assertf( expr, "expected a non-null expression" );
     1108                       
     1109                        // set up and resolve expression cast to void
     1110                        ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr };
     1111                        CandidateRef choice = findUnfinishedKindExpression(
     1112                                untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
     1113                       
     1114                        // a cast expression has either 0 or 1 interpretations (by language rules);
     1115                        // if 0, an exception has already been thrown, and this code will not run
     1116                        const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >();
     1117                        env = std::move( choice->env );
     1118
     1119                        return castExpr->arg;
     1120                }
     1121
    11241122                /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    11251123                /// context.
     
    11481146                }
    11491147
    1150                 /// Resolve `untyped` to the single expression whose candidate is the best match
    1151                 ast::ptr< ast::Expr > findSingleExpression(
    1152                         const ast::Expr * untyped, const ast::SymbolTable & symtab
    1153                 ) {
    1154                         return findKindExpression( untyped, symtab );
    1155                 }
    1156 
    11571148                /// Resolve `untyped` to the single expression whose candidate is the best match for the
    11581149                /// given type.
     
    11611152                ) {
    11621153                        assert( untyped && type );
    1163                         ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped->location, untyped, type };
    1164                         ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
     1154                        const ast::Expr * castExpr = new ast::CastExpr{ untyped->location, untyped, type };
     1155                        ast::ptr< ast::Expr > newExpr = findKindExpression( castExpr, symtab );
    11651156                        removeExtraneousCast( newExpr, symtab );
    11661157                        return newExpr;
     
    11981189                        return false;
    11991190                }
    1200 
    1201                 /// Advance a type itertor to the next mutex parameter
    1202                 template<typename Iter>
    1203                 inline bool nextMutex( Iter & it, const Iter & end ) {
    1204                         while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
    1205                         return it != end;
    1206                 }
    12071191        }
    12081192
     
    12291213                void previsit( const ast::PointerType * );
    12301214
    1231                 const ast::ExprStmt *        previsit( const ast::ExprStmt * );
    1232                 const ast::AsmExpr *         previsit( const ast::AsmExpr * );
    1233                 const ast::AsmStmt *         previsit( const ast::AsmStmt * );
    1234                 const ast::IfStmt *          previsit( const ast::IfStmt * );
    1235                 const ast::WhileStmt *       previsit( const ast::WhileStmt * );
    1236                 const ast::ForStmt *         previsit( const ast::ForStmt * );
    1237                 const ast::SwitchStmt *      previsit( const ast::SwitchStmt * );
    1238                 const ast::CaseStmt *        previsit( const ast::CaseStmt * );
    1239                 const ast::BranchStmt *      previsit( const ast::BranchStmt * );
    1240                 const ast::ReturnStmt *      previsit( const ast::ReturnStmt * );
    1241                 const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
    1242                 const ast::CatchStmt *       previsit( const ast::CatchStmt * );
    1243                 const ast::WaitForStmt *    previsit( const ast::WaitForStmt * );
    1244 
    1245                 const ast::SingleInit *      previsit( const ast::SingleInit * );
    1246                 const ast::ListInit *        previsit( const ast::ListInit * );
    1247                 const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
     1215                const ast::ExprStmt *   previsit( const ast::ExprStmt * );
     1216                const ast::AsmExpr *    previsit( const ast::AsmExpr * );
     1217                const ast::AsmStmt *    previsit( const ast::AsmStmt * );
     1218                const ast::IfStmt *     previsit( const ast::IfStmt * );
     1219                const ast::WhileStmt *  previsit( const ast::WhileStmt * );
     1220                const ast::ForStmt *    previsit( const ast::ForStmt * );
     1221                const ast::SwitchStmt * previsit( const ast::SwitchStmt * );
     1222                const ast::CaseStmt *   previsit( const ast::CaseStmt * );
     1223                const ast::BranchStmt * previsit( const ast::BranchStmt * );
     1224                const ast::ReturnStmt * previsit( const ast::ReturnStmt * );
     1225                const ast::ThrowStmt *  previsit( const ast::ThrowStmt * );
     1226                const ast::CatchStmt *  previsit( const ast::CatchStmt * );
     1227                void previsit( const ast::WaitForStmt * );
     1228
     1229                const ast::SingleInit * previsit( const ast::SingleInit * );
     1230                const ast::ListInit * previsit( const ast::ListInit * );
     1231                void previsit( const ast::ConstructorInit * );
    12481232        };
    12491233
     
    13971381                                "expression." );
    13981382                       
    1399                         ast::ptr< ast::Expr > untyped =
     1383                        const ast::Expr * untyped =
    14001384                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
    1401                         ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
     1385                        ast::ptr< ast::Expr > newExpr = findKindExpression( untyped, symtab );
    14021386                       
    14031387                        // case condition cannot have a cast in C, so it must be removed here, regardless of
     
    14171401                if ( branchStmt->kind == ast::BranchStmt::Goto && branchStmt->computedTarget ) {
    14181402                        // computed goto argument is void*
    1419                         ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
    14201403                        branchStmt = ast::mutate_field(
    14211404                                branchStmt, &ast::BranchStmt::computedTarget,
    1422                                 findSingleExpression( branchStmt->computedTarget, target, symtab ) );
     1405                                findSingleExpression(
     1406                                        branchStmt->computedTarget, new ast::PointerType{ new ast::VoidType{} },
     1407                                        symtab ) );
    14231408                }
    14241409                return branchStmt;
     
    14601445        }
    14611446
    1462         const ast::WaitForStmt * Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
    1463                 visit_children = false;
    1464 
    1465                 // Resolve all clauses first
    1466                 for ( unsigned i = 0; i < stmt->clauses.size(); ++i ) {
    1467                         const ast::WaitForStmt::Clause & clause = stmt->clauses[i];
    1468 
    1469                         ast::TypeEnvironment env;
    1470                         CandidateFinder funcFinder{ symtab, env };
    1471 
    1472                         // Find all candidates for a function in canonical form
    1473                         funcFinder.find( clause.target.func, ResolvMode::withAdjustment() );
    1474 
    1475                         if ( funcFinder.candidates.empty() ) {
    1476                                 stringstream ss;
    1477                                 ss << "Use of undeclared indentifier '";
    1478                                 ss << clause.target.func.strict_as< ast::NameExpr >()->name;
    1479                                 ss << "' in call to waitfor";
    1480                                 SemanticError( stmt->location, ss.str() );
    1481                         }
    1482 
    1483                         if ( clause.target.args.empty() ) {
    1484                                 SemanticError( stmt->location,
    1485                                         "Waitfor clause must have at least one mutex parameter");
    1486                         }
    1487 
    1488                         // Find all alternatives for all arguments in canonical form
    1489                         std::vector< CandidateFinder > argFinders =
    1490                                 funcFinder.findSubExprs( clause.target.args );
    1491                        
    1492                         // List all combinations of arguments
    1493                         std::vector< CandidateList > possibilities;
    1494                         combos( argFinders.begin(), argFinders.end(), back_inserter( possibilities ) );
    1495 
    1496                         // For every possible function:
    1497                         // * try matching the arguments to the parameters, not the other way around because
    1498                         //   more arguments than parameters
    1499                         CandidateList funcCandidates;
    1500                         std::vector< CandidateList > argsCandidates;
    1501                         SemanticErrorException errors;
    1502                         for ( CandidateRef & func : funcFinder.candidates ) {
    1503                                 try {
    1504                                         auto pointerType = dynamic_cast< const ast::PointerType * >(
    1505                                                 func->expr->result->stripReferences() );
    1506                                         if ( ! pointerType ) {
    1507                                                 SemanticError( stmt->location, func->expr->result.get(),
    1508                                                         "candidate not viable: not a pointer type\n" );
    1509                                         }
    1510 
    1511                                         auto funcType = pointerType->base.as< ast::FunctionType >();
    1512                                         if ( ! funcType ) {
    1513                                                 SemanticError( stmt->location, func->expr->result.get(),
    1514                                                         "candidate not viable: not a function type\n" );
    1515                                         }
    1516 
    1517                                         {
    1518                                                 auto param    = funcType->params.begin();
    1519                                                 auto paramEnd = funcType->params.end();
    1520 
    1521                                                 if( ! nextMutex( param, paramEnd ) ) {
    1522                                                         SemanticError( stmt->location, funcType,
    1523                                                                 "candidate function not viable: no mutex parameters\n");
    1524                                                 }
    1525                                         }
    1526 
    1527                                         CandidateRef func2{ new Candidate{ *func } };
    1528                                         // strip reference from function
    1529                                         func2->expr = referenceToRvalueConversion( func->expr, func2->cost );
    1530 
    1531                                         // Each argument must be matched with a parameter of the current candidate
    1532                                         for ( auto & argsList : possibilities ) {
    1533                                                 try {
    1534                                                         // Declare data structures needed for resolution
    1535                                                         ast::OpenVarSet open;
    1536                                                         ast::AssertionSet need, have;
    1537                                                         ast::TypeEnvironment resultEnv{ func->env };
    1538                                                         // Add all type variables as open so that those not used in the
    1539                                                         // parameter list are still considered open
    1540                                                         resultEnv.add( funcType->forall );
    1541 
    1542                                                         // load type variables from arguments into one shared space
    1543                                                         for ( auto & arg : argsList ) {
    1544                                                                 resultEnv.simpleCombine( arg->env );
    1545                                                         }
    1546 
    1547                                                         // Make sure we don't widen any existing bindings
    1548                                                         resultEnv.forbidWidening();
    1549 
    1550                                                         // Find any unbound type variables
    1551                                                         resultEnv.extractOpenVars( open );
    1552 
    1553                                                         auto param = funcType->params.begin();
    1554                                                         auto paramEnd = funcType->params.end();
    1555 
    1556                                                         unsigned n_mutex_param = 0;
    1557 
    1558                                                         // For every argument of its set, check if it matches one of the
    1559                                                         // parameters. The order is important
    1560                                                         for ( auto & arg : argsList ) {
    1561                                                                 // Ignore non-mutex arguments
    1562                                                                 if ( ! nextMutex( param, paramEnd ) ) {
    1563                                                                         // We ran out of parameters but still have arguments.
    1564                                                                         // This function doesn't match
    1565                                                                         SemanticError( stmt->location, funcType,
    1566                                                                                 toString("candidate function not viable: too many mutex "
    1567                                                                                 "arguments, expected ", n_mutex_param, "\n" ) );
    1568                                                                 }
    1569 
    1570                                                                 ++n_mutex_param;
    1571 
    1572                                                                 // Check if the argument matches the parameter type in the current
    1573                                                                 // scope
    1574                                                                 ast::ptr< ast::Type > paramType = (*param)->get_type();
    1575                                                                 if (
    1576                                                                         ! unify(
    1577                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
    1578                                                                                 symtab )
    1579                                                                 ) {
    1580                                                                         // Type doesn't match
    1581                                                                         stringstream ss;
    1582                                                                         ss << "candidate function not viable: no known conversion "
    1583                                                                                 "from '";
    1584                                                                         ast::print( ss, (*param)->get_type() );
    1585                                                                         ss << "' to '";
    1586                                                                         ast::print( ss, arg->expr->result );
    1587                                                                         ss << "' with env '";
    1588                                                                         ast::print( ss, resultEnv );
    1589                                                                         ss << "'\n";
    1590                                                                         SemanticError( stmt->location, funcType, ss.str() );
    1591                                                                 }
    1592 
    1593                                                                 ++param;
    1594                                                         }
    1595 
    1596                                                         // All arguments match!
    1597 
    1598                                                         // Check if parameters are missing
    1599                                                         if ( nextMutex( param, paramEnd ) ) {
    1600                                                                 do {
    1601                                                                         ++n_mutex_param;
    1602                                                                         ++param;
    1603                                                                 } while ( nextMutex( param, paramEnd ) );
    1604 
    1605                                                                 // We ran out of arguments but still have parameters left; this
    1606                                                                 // function doesn't match
    1607                                                                 SemanticError( stmt->location, funcType,
    1608                                                                         toString( "candidate function not viable: too few mutex "
    1609                                                                         "arguments, expected ", n_mutex_param, "\n" ) );
    1610                                                         }
    1611 
    1612                                                         // All parameters match!
    1613 
    1614                                                         // Finish the expressions to tie in proper environments
    1615                                                         finishExpr( func2->expr, resultEnv );
    1616                                                         for ( CandidateRef & arg : argsList ) {
    1617                                                                 finishExpr( arg->expr, resultEnv );
    1618                                                         }
    1619 
    1620                                                         // This is a match, store it and save it for later
    1621                                                         funcCandidates.emplace_back( std::move( func2 ) );
    1622                                                         argsCandidates.emplace_back( std::move( argsList ) );
    1623 
    1624                                                 } catch ( SemanticErrorException & e ) {
    1625                                                         errors.append( e );
    1626                                                 }
    1627                                         }
    1628                                 } catch ( SemanticErrorException & e ) {
    1629                                         errors.append( e );
    1630                                 }
    1631                         }
    1632 
    1633                         // Make sure correct number of arguments
    1634                         if( funcCandidates.empty() ) {
    1635                                 SemanticErrorException top( stmt->location,
    1636                                         "No alternatives for function in call to waitfor" );
    1637                                 top.append( errors );
    1638                                 throw top;
    1639                         }
    1640 
    1641                         if( argsCandidates.empty() ) {
    1642                                 SemanticErrorException top( stmt->location,
    1643                                         "No alternatives for arguments in call to waitfor" );
    1644                                 top.append( errors );
    1645                                 throw top;
    1646                         }
    1647 
    1648                         if( funcCandidates.size() > 1 ) {
    1649                                 SemanticErrorException top( stmt->location,
    1650                                         "Ambiguous function in call to waitfor" );
    1651                                 top.append( errors );
    1652                                 throw top;
    1653                         }
    1654                         if( argsCandidates.size() > 1 ) {
    1655                                 SemanticErrorException top( stmt->location,
    1656                                         "Ambiguous arguments in call to waitfor" );
    1657                                 top.append( errors );
    1658                                 throw top;
    1659                         }
    1660                         // TODO: need to use findDeletedExpr to ensure no deleted identifiers are used.
    1661 
    1662                         // build new clause
    1663                         ast::WaitForStmt::Clause clause2;
    1664                        
    1665                         clause2.target.func = funcCandidates.front()->expr;
    1666                        
    1667                         clause2.target.args.reserve( clause.target.args.size() );
    1668                         for ( auto arg : argsCandidates.front() ) {
    1669                                 clause2.target.args.emplace_back( std::move( arg->expr ) );
    1670                         }
    1671 
    1672                         // Resolve the conditions as if it were an IfStmt, statements normally
    1673                         clause2.cond = findSingleExpression( clause.cond, symtab );
    1674                         clause2.stmt = clause.stmt->accept( *visitor );
    1675 
    1676                         // set results into stmt
    1677                         auto n = mutate( stmt );
    1678                         n->clauses[i] = std::move( clause2 );
    1679                         stmt = n;
    1680                 }
    1681 
    1682                 if ( stmt->timeout.stmt ) {
    1683                         // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally
    1684                         ast::WaitForStmt::Timeout timeout2;
    1685 
    1686                         ast::ptr< ast::Type > target =
    1687                                 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
    1688                         timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
    1689                         timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab );
    1690                         timeout2.stmt = stmt->timeout.stmt->accept( *visitor );
    1691 
    1692                         // set results into stmt
    1693                         auto n = mutate( stmt );
    1694                         n->timeout = std::move( timeout2 );
    1695                         stmt = n;
    1696                 }
    1697 
    1698                 if ( stmt->orElse.stmt ) {
    1699                         // resolve the condition like IfStmt, stmts normally
    1700                         ast::WaitForStmt::OrElse orElse2;
    1701 
    1702                         orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab );
    1703                         orElse2.stmt = stmt->orElse.stmt->accept( *visitor );
    1704 
    1705                         // set results into stmt
    1706                         auto n = mutate( stmt );
    1707                         n->orElse = std::move( orElse2 );
    1708                         stmt = n;
    1709                 }
    1710 
    1711                 return stmt;
     1447        void Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
     1448                #warning unimplemented; Resolver port in progress
     1449                (void)stmt;
     1450                assert(false);
    17121451        }
    17131452
     
    17181457                // resolve initialization using the possibilities as determined by the `currentObject`
    17191458                // cursor.
    1720                 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
     1459                ast::Expr * untyped = new ast::UntypedInitExpr{
    17211460                        singleInit->location, singleInit->value, currentObject.getOptions() };
    1722                 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
     1461                ast::ptr<ast::Expr> newExpr = findKindExpression( untyped, symtab );
    17231462                const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >();
    17241463
     
    17711510                        // iterate designations and initializers in pairs, moving the cursor to the current
    17721511                        // designated object and resolving the initializer against that object
    1773                         listInit = ast::mutate_field_index(
    1774                                 listInit, &ast::ListInit::designations, i,
    1775                                 currentObject.findNext( listInit->designations[i] ) );
    1776                         listInit = ast::mutate_field_index(
    1777                                 listInit, &ast::ListInit::initializers, i,
    1778                                 listInit->initializers[i]->accept( *visitor ) );
    1779                 }
    1780 
    1781                 // move cursor out of brace-enclosed initializer-list
    1782                 currentObject.exitListInit();
     1512                        #warning unimplemented; Resolver port in progress
     1513                        assert(false);
     1514                }
    17831515
    17841516                visit_children = false;
     
    17861518        }
    17871519
    1788         const ast::ConstructorInit * Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
    1789                 visitor->maybe_accept( ctorInit, &ast::ConstructorInit::ctor );
    1790                 visitor->maybe_accept( ctorInit, &ast::ConstructorInit::dtor );
    1791 
    1792                 // found a constructor - can get rid of C-style initializer
    1793                 // xxx - Rob suggests this field is dead code
    1794                 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
    1795 
    1796                 // intrinsic single-parameter constructors and destructors do nothing. Since this was
    1797                 // implicitly generated, there's no way for it to have side effects, so get rid of it to
    1798                 // clean up generated code
    1799                 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
    1800                         ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::ctor, nullptr );
    1801                 }
    1802                 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
    1803                         ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::dtor, nullptr );
    1804                 }
    1805 
    1806                 return ctorInit;
     1520        void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
     1521                #warning unimplemented; Resolver port in progress
     1522                (void)ctorInit;
     1523                assert(false);
    18071524        }
    18081525
Note: See TracChangeset for help on using the changeset viewer.