Changeset 6ad19fd


Ignore:
Timestamp:
Jun 10, 2019, 9:37:23 PM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
8548c35
Parents:
b326277 (diff), 396037d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.in

    rb326277 r6ad19fd  
    203203        ResolvExpr/Resolver.$(OBJEXT) \
    204204        ResolvExpr/ResolveTypeof.$(OBJEXT) \
     205        ResolvExpr/SatisfyAssertions.$(OBJEXT) \
    205206        ResolvExpr/SpecCost.$(OBJEXT) \
    206207        ResolvExpr/TypeEnvironment.$(OBJEXT) \
     
    641642      ResolvExpr/Resolver.cc \
    642643      ResolvExpr/ResolveTypeof.cc \
     644      ResolvExpr/SatisfyAssertions.cpp \
    643645      ResolvExpr/SpecCost.cc \
    644646      ResolvExpr/TypeEnvironment.cc \
     
    911913ResolvExpr/ResolveTypeof.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    912914        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     915ResolvExpr/SatisfyAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     916        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    913917ResolvExpr/SpecCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    914918        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     
    12821286@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveTypeof.Po@am__quote@
    12831287@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Resolver.Po@am__quote@
     1288@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SatisfyAssertions.Po@am__quote@
    12841289@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SpecCost.Po@am__quote@
    12851290@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/TypeEnvironment.Po@am__quote@
  • src/ResolvExpr/AlternativeFinder.cc

    rb326277 r6ad19fd  
    266266                        SemanticError( expr, "No reasonable alternatives for expression " );
    267267                }
    268                 if ( mode.resolveAssns || mode.prune ) {
     268                if ( mode.satisfyAssns || mode.prune ) {
    269269                        // trim candidates just to those where the assertions resolve
    270270                        // - necessary pre-requisite to pruning
  • src/ResolvExpr/CandidateFinder.cpp

    rb326277 r6ad19fd  
    1616#include "CandidateFinder.hpp"
    1717
     18#include <sstream>
     19
     20#include "Candidate.hpp"
     21#include "CompilationState.h"
     22#include "SatisfyAssertions.hpp"
    1823#include "AST/Expr.hpp"
     24#include "AST/Node.hpp"
     25#include "AST/Pass.hpp"
     26
     27#define PRINT( text ) if ( resolvep ) { text }
    1928
    2029namespace ResolvExpr {
    2130
     31namespace {
     32
     33        /// Actually visits expressions to find their candidate interpretations
     34        struct Finder {
     35                CandidateFinder & candFinder;
     36                const ast::SymbolTable & symtab;
     37                CandidateList & candidates;
     38                const ast::TypeEnvironment & tenv;
     39                ast::ptr< ast::Type > & targetType;
     40
     41                Finder( CandidateFinder & f )
     42                : candFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),
     43                  targetType( f.targetType ) {}
     44               
     45                #warning unimplemented
     46        };
     47
     48        /// Prunes a list of candidates down to those that have the minimum conversion cost for a given
     49        /// return type. Skips ambiguous candidates.
     50        CandidateList pruneCandidates( CandidateList & candidates ) {
     51                #warning unimplemented
     52                (void)candidates;
     53                assert(false);
     54                return {};
     55        }
     56
     57} // anonymous namespace
     58
    2259void CandidateFinder::find( const ast::Expr * expr, ResolvMode mode ) {
     60        // Find alternatives for expression
     61        ast::Pass<Finder> finder{ *this };
     62        expr->accept( finder );
     63
     64        if ( mode.failFast && candidates.empty() ) {
     65                SemanticError( expr, "No reasonable alternatives for expression " );
     66        }
     67
     68        if ( mode.satisfyAssns || mode.prune ) {
     69                // trim candidates to just those where the assertions are satisfiable
     70                // - necessary pre-requisite to pruning
     71                CandidateList satisfied;
     72                std::vector< std::string > errors;
     73                for ( auto & candidate : candidates ) {
     74                        satisfyAssertions( *candidate, symtab, satisfied, errors );
     75                }
     76
     77                // fail early if none such
     78                if ( mode.failFast && satisfied.empty() ) {
     79                        std::ostringstream stream;
     80                        stream << "No alternatives with satisfiable assertions for " << expr << "\n";
     81                        for ( const auto& err : errors ) {
     82                                stream << err;
     83                        }
     84                        SemanticError( expr->location, stream.str() );
     85                }
     86
     87                // reset candidates
     88                candidates = std::move( satisfied );
     89        }
     90
     91        if ( mode.prune ) {
     92                // trim candidates to single best one
     93                auto oldsize = candidates.size();
     94                PRINT(
     95                        std::cerr << "alternatives before prune:" << std::endl;
     96                        print( std::cerr, candidates );
     97                )
     98
     99                CandidateList pruned = pruneCandidates( candidates );
     100                if ( mode.failFast && pruned.empty() ) {
     101                        std::ostringstream stream;
     102                        CandidateList winners;
     103                       
     104                        #warning unimplemented
     105                        assert(false);
     106                }
     107        }
     108
    23109        #warning unimplemented
    24         (void)expr; (void)mode;
    25110        assert(false);
     111}
     112
     113std::vector< CandidateFinder > CandidateFinder::findSubExprs(
     114        const std::vector< ast::ptr< ast::Expr > > & xs
     115) {
     116        std::vector< CandidateFinder > out;
     117
     118        for ( const auto & x : xs ) {
     119                out.emplace_back( symtab, env );
     120                out.back().find( x, ResolvMode::withAdjustment() );
     121               
     122                PRINT(
     123                        std::cerr << "findSubExprs" << std::endl;
     124                        print( std::cerr, out.back().candidates );
     125                )
     126        }
     127
     128        return out;
    26129}
    27130
  • src/ResolvExpr/CandidateFinder.hpp

    rb326277 r6ad19fd  
    1919#include "ResolvMode.h"
    2020#include "AST/Fwd.hpp"
     21#include "AST/Node.hpp"
    2122#include "AST/SymbolTable.hpp"
    2223#include "AST/TypeEnvironment.hpp"
     
    2930        const ast::SymbolTable & symtab;         ///< Symbol table to lookup candidates
    3031        const ast::TypeEnvironment & env;        ///< Substitutions performed in this resolution
    31         const ast::Type * targetType = nullptr;  ///< Target type for resolution
     32        ast::ptr< ast::Type > targetType = nullptr;  ///< Target type for resolution
    3233
    3334        CandidateFinder( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env )
     
    3637        /// Fill candidates with feasible resolutions for `expr`
    3738        void find( const ast::Expr * expr, ResolvMode mode = {} );
     39
     40        /// Runs new candidate finder on each element in xs, returning the list of finders
     41        std::vector< CandidateFinder > findSubExprs( const std::vector< ast::ptr< ast::Expr > > & xs );
     42
     43        using value_type = CandidateList::value_type;
     44        using iterator = CandidateList::iterator;
     45        using const_iterator = CandidateList::const_iterator;
     46
     47        iterator begin() { return candidates.begin(); }
     48        const_iterator begin() const { return candidates.begin(); }
     49       
     50        iterator end() { return candidates.end(); }
     51        const_iterator end() const { return candidates.end(); }
    3852};
    3953
  • src/ResolvExpr/ResolvMode.h

    rb326277 r6ad19fd  
    2222                const bool prune;            ///< Prune alternatives to min-cost per return type? [true]
    2323                const bool failFast;         ///< Fail on no resulting alternatives? [true]
    24                 const bool resolveAssns;     ///< Resolve assertions? [false]
     24                const bool satisfyAssns;     ///< Satisfy assertions? [false]
    2525
    2626        private:
    27                 constexpr ResolvMode(bool a, bool p, bool ff, bool ra)
    28                 : adjust(a), prune(p), failFast(ff), resolveAssns(ra) {}
     27                constexpr ResolvMode(bool a, bool p, bool ff, bool sa)
     28                : adjust(a), prune(p), failFast(ff), satisfyAssns(sa) {}
    2929
    3030        public:
    3131                /// Default settings
    32                 constexpr ResolvMode() : adjust(false), prune(true), failFast(true), resolveAssns(false) {}
     32                constexpr ResolvMode() : adjust(false), prune(true), failFast(true), satisfyAssns(false) {}
    3333               
    3434                /// With adjust flag set; turns array and function types into equivalent pointers
     
    4343                static constexpr ResolvMode withoutFailFast() { return { true, true, false, false }; }
    4444
    45                 /// The same mode, but with resolveAssns turned on; for top-level calls
     45                /// The same mode, but with satisfyAssns turned on; for top-level calls
    4646                ResolvMode atTopLevel() const { return { adjust, prune, failFast, true }; }
    4747        };
  • src/ResolvExpr/Resolver.cc

    rb326277 r6ad19fd  
    3535#include "AST/Print.hpp"
    3636#include "AST/SymbolTable.hpp"
     37#include "AST/Type.hpp"
    3738#include "Common/PassVisitor.h"          // for PassVisitor
    3839#include "Common/SemanticError.h"        // for SemanticError
     
    11461147                }
    11471148
     1149                /// Resolve `untyped` to the single expression whose candidate is the best match
     1150                ast::ptr< ast::Expr > findSingleExpression(
     1151                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1152                ) {
     1153                        return findKindExpression( untyped, symtab );
     1154                }
     1155
    11481156                /// Resolve `untyped` to the single expression whose candidate is the best match for the
    11491157                /// given type.
     
    11521160                ) {
    11531161                        assert( untyped && type );
    1154                         const ast::Expr * castExpr = new ast::CastExpr{ untyped->location, untyped, type };
    1155                         ast::ptr< ast::Expr > newExpr = findKindExpression( castExpr, symtab );
     1162                        ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped->location, untyped, type };
     1163                        ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
    11561164                        removeExtraneousCast( newExpr, symtab );
    11571165                        return newExpr;
     
    11891197                        return false;
    11901198                }
     1199
     1200                /// Advance a type itertor to the next mutex parameter
     1201                template<typename Iter>
     1202                inline bool nextMutex( Iter & it, const Iter & end ) {
     1203                        while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1204                        return it != end;
     1205                }
    11911206        }
    11921207
     
    12131228                void previsit( const ast::PointerType * );
    12141229
    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 * );
     1230                const ast::ExprStmt *        previsit( const ast::ExprStmt * );
     1231                const ast::AsmExpr *         previsit( const ast::AsmExpr * );
     1232                const ast::AsmStmt *         previsit( const ast::AsmStmt * );
     1233                const ast::IfStmt *          previsit( const ast::IfStmt * );
     1234                const ast::WhileStmt *       previsit( const ast::WhileStmt * );
     1235                const ast::ForStmt *         previsit( const ast::ForStmt * );
     1236                const ast::SwitchStmt *      previsit( const ast::SwitchStmt * );
     1237                const ast::CaseStmt *        previsit( const ast::CaseStmt * );
     1238                const ast::BranchStmt *      previsit( const ast::BranchStmt * );
     1239                const ast::ReturnStmt *      previsit( const ast::ReturnStmt * );
     1240                const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
     1241                const ast::CatchStmt *       previsit( const ast::CatchStmt * );
     1242                const ast::WaitForStmt *    previsit( const ast::WaitForStmt * );
    12281243
    12291244                const ast::SingleInit *      previsit( const ast::SingleInit * );
     
    13811396                                "expression." );
    13821397                       
    1383                         const ast::Expr * untyped =
     1398                        ast::ptr< ast::Expr > untyped =
    13841399                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
    1385                         ast::ptr< ast::Expr > newExpr = findKindExpression( untyped, symtab );
     1400                        ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
    13861401                       
    13871402                        // case condition cannot have a cast in C, so it must be removed here, regardless of
     
    14011416                if ( branchStmt->kind == ast::BranchStmt::Goto && branchStmt->computedTarget ) {
    14021417                        // computed goto argument is void*
     1418                        ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
    14031419                        branchStmt = ast::mutate_field(
    14041420                                branchStmt, &ast::BranchStmt::computedTarget,
    1405                                 findSingleExpression(
    1406                                         branchStmt->computedTarget, new ast::PointerType{ new ast::VoidType{} },
    1407                                         symtab ) );
     1421                                findSingleExpression( branchStmt->computedTarget, target, symtab ) );
    14081422                }
    14091423                return branchStmt;
     
    14451459        }
    14461460
    1447         void Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
    1448                 #warning unimplemented; Resolver port in progress
    1449                 (void)stmt;
    1450                 assert(false);
     1461        const ast::WaitForStmt * Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
     1462                visit_children = false;
     1463
     1464                // Resolve all clauses first
     1465                for ( unsigned i = 0; i < stmt->clauses.size(); ++i ) {
     1466                        const ast::WaitForStmt::Clause & clause = stmt->clauses[i];
     1467
     1468                        ast::TypeEnvironment env;
     1469                        CandidateFinder funcFinder{ symtab, env };
     1470
     1471                        // Find all candidates for a function in canonical form
     1472                        funcFinder.find( clause.target.func, ResolvMode::withAdjustment() );
     1473
     1474                        if ( funcFinder.candidates.empty() ) {
     1475                                stringstream ss;
     1476                                ss << "Use of undeclared indentifier '";
     1477                                ss << clause.target.func.strict_as< ast::NameExpr >()->name;
     1478                                ss << "' in call to waitfor";
     1479                                SemanticError( stmt->location, ss.str() );
     1480                        }
     1481
     1482                        if ( clause.target.args.empty() ) {
     1483                                SemanticError( stmt->location,
     1484                                        "Waitfor clause must have at least one mutex parameter");
     1485                        }
     1486
     1487                        // Find all alternatives for all arguments in canonical form
     1488                        std::vector< CandidateFinder > argFinders =
     1489                                funcFinder.findSubExprs( clause.target.args );
     1490                       
     1491                        // List all combinations of arguments
     1492                        std::vector< CandidateList > possibilities;
     1493                        combos( argFinders.begin(), argFinders.end(), back_inserter( possibilities ) );
     1494
     1495                        // For every possible function:
     1496                        // * try matching the arguments to the parameters, not the other way around because
     1497                        //   more arguments than parameters
     1498                        CandidateList funcCandidates;
     1499                        std::vector< CandidateList > argsCandidates;
     1500                        SemanticErrorException errors;
     1501                        for ( CandidateRef & func : funcFinder.candidates ) {
     1502                                try {
     1503                                        auto pointerType = dynamic_cast< const ast::PointerType * >(
     1504                                                func->expr->result->stripReferences() );
     1505                                        if ( ! pointerType ) {
     1506                                                SemanticError( stmt->location, func->expr->result.get(),
     1507                                                        "candidate not viable: not a pointer type\n" );
     1508                                        }
     1509
     1510                                        auto funcType = pointerType->base.as< ast::FunctionType >();
     1511                                        if ( ! funcType ) {
     1512                                                SemanticError( stmt->location, func->expr->result.get(),
     1513                                                        "candidate not viable: not a function type\n" );
     1514                                        }
     1515
     1516                                        {
     1517                                                auto param    = funcType->params.begin();
     1518                                                auto paramEnd = funcType->params.end();
     1519
     1520                                                if( ! nextMutex( param, paramEnd ) ) {
     1521                                                        SemanticError( stmt->location, funcType,
     1522                                                                "candidate function not viable: no mutex parameters\n");
     1523                                                }
     1524                                        }
     1525
     1526                                        CandidateRef func2{ new Candidate{ *func } };
     1527                                        // strip reference from function
     1528                                        func2->expr = referenceToRvalueConversion( func->expr, func2->cost );
     1529
     1530                                        // Each argument must be matched with a parameter of the current candidate
     1531                                        for ( auto & argsList : possibilities ) {
     1532                                                try {
     1533                                                        // Declare data structures needed for resolution
     1534                                                        ast::OpenVarSet open;
     1535                                                        ast::AssertionSet need, have;
     1536                                                        ast::TypeEnvironment resultEnv{ func->env };
     1537                                                        // Add all type variables as open so that those not used in the
     1538                                                        // parameter list are still considered open
     1539                                                        resultEnv.add( funcType->forall );
     1540
     1541                                                        // load type variables from arguments into one shared space
     1542                                                        for ( auto & arg : argsList ) {
     1543                                                                resultEnv.simpleCombine( arg->env );
     1544                                                        }
     1545
     1546                                                        // Make sure we don't widen any existing bindings
     1547                                                        resultEnv.forbidWidening();
     1548
     1549                                                        // Find any unbound type variables
     1550                                                        resultEnv.extractOpenVars( open );
     1551
     1552                                                        auto param = funcType->params.begin();
     1553                                                        auto paramEnd = funcType->params.end();
     1554
     1555                                                        unsigned n_mutex_param = 0;
     1556
     1557                                                        // For every argument of its set, check if it matches one of the
     1558                                                        // parameters. The order is important
     1559                                                        for ( auto & arg : argsList ) {
     1560                                                                // Ignore non-mutex arguments
     1561                                                                if ( ! nextMutex( param, paramEnd ) ) {
     1562                                                                        // We ran out of parameters but still have arguments.
     1563                                                                        // This function doesn't match
     1564                                                                        SemanticError( stmt->location, funcType,
     1565                                                                                toString("candidate function not viable: too many mutex "
     1566                                                                                "arguments, expected ", n_mutex_param, "\n" ) );
     1567                                                                }
     1568
     1569                                                                ++n_mutex_param;
     1570
     1571                                                                // Check if the argument matches the parameter type in the current
     1572                                                                // scope
     1573                                                                ast::ptr< ast::Type > paramType = (*param)->get_type();
     1574                                                                if (
     1575                                                                        ! unify(
     1576                                                                                arg->expr->result, paramType, resultEnv, need, have, open,
     1577                                                                                symtab )
     1578                                                                ) {
     1579                                                                        // Type doesn't match
     1580                                                                        stringstream ss;
     1581                                                                        ss << "candidate function not viable: no known conversion "
     1582                                                                                "from '";
     1583                                                                        ast::print( ss, (*param)->get_type() );
     1584                                                                        ss << "' to '";
     1585                                                                        ast::print( ss, arg->expr->result );
     1586                                                                        ss << "' with env '";
     1587                                                                        ast::print( ss, resultEnv );
     1588                                                                        ss << "'\n";
     1589                                                                        SemanticError( stmt->location, funcType, ss.str() );
     1590                                                                }
     1591
     1592                                                                ++param;
     1593                                                        }
     1594
     1595                                                        // All arguments match!
     1596
     1597                                                        // Check if parameters are missing
     1598                                                        if ( nextMutex( param, paramEnd ) ) {
     1599                                                                do {
     1600                                                                        ++n_mutex_param;
     1601                                                                        ++param;
     1602                                                                } while ( nextMutex( param, paramEnd ) );
     1603
     1604                                                                // We ran out of arguments but still have parameters left; this
     1605                                                                // function doesn't match
     1606                                                                SemanticError( stmt->location, funcType,
     1607                                                                        toString( "candidate function not viable: too few mutex "
     1608                                                                        "arguments, expected ", n_mutex_param, "\n" ) );
     1609                                                        }
     1610
     1611                                                        // All parameters match!
     1612
     1613                                                        // Finish the expressions to tie in proper environments
     1614                                                        finishExpr( func2->expr, resultEnv );
     1615                                                        for ( CandidateRef & arg : argsList ) {
     1616                                                                finishExpr( arg->expr, resultEnv );
     1617                                                        }
     1618
     1619                                                        // This is a match, store it and save it for later
     1620                                                        funcCandidates.emplace_back( std::move( func2 ) );
     1621                                                        argsCandidates.emplace_back( std::move( argsList ) );
     1622
     1623                                                } catch ( SemanticErrorException & e ) {
     1624                                                        errors.append( e );
     1625                                                }
     1626                                        }
     1627                                } catch ( SemanticErrorException & e ) {
     1628                                        errors.append( e );
     1629                                }
     1630                        }
     1631
     1632                        // Make sure correct number of arguments
     1633                        if( funcCandidates.empty() ) {
     1634                                SemanticErrorException top( stmt->location,
     1635                                        "No alternatives for function in call to waitfor" );
     1636                                top.append( errors );
     1637                                throw top;
     1638                        }
     1639
     1640                        if( argsCandidates.empty() ) {
     1641                                SemanticErrorException top( stmt->location,
     1642                                        "No alternatives for arguments in call to waitfor" );
     1643                                top.append( errors );
     1644                                throw top;
     1645                        }
     1646
     1647                        if( funcCandidates.size() > 1 ) {
     1648                                SemanticErrorException top( stmt->location,
     1649                                        "Ambiguous function in call to waitfor" );
     1650                                top.append( errors );
     1651                                throw top;
     1652                        }
     1653                        if( argsCandidates.size() > 1 ) {
     1654                                SemanticErrorException top( stmt->location,
     1655                                        "Ambiguous arguments in call to waitfor" );
     1656                                top.append( errors );
     1657                                throw top;
     1658                        }
     1659                        // TODO: need to use findDeletedExpr to ensure no deleted identifiers are used.
     1660
     1661                        // build new clause
     1662                        ast::WaitForStmt::Clause clause2;
     1663                       
     1664                        clause2.target.func = funcCandidates.front()->expr;
     1665                       
     1666                        clause2.target.args.reserve( clause.target.args.size() );
     1667                        for ( auto arg : argsCandidates.front() ) {
     1668                                clause2.target.args.emplace_back( std::move( arg->expr ) );
     1669                        }
     1670
     1671                        // Resolve the conditions as if it were an IfStmt, statements normally
     1672                        clause2.cond = findSingleExpression( clause.cond, symtab );
     1673                        clause2.stmt = clause.stmt->accept( *visitor );
     1674
     1675                        // set results into stmt
     1676                        auto n = mutate( stmt );
     1677                        n->clauses[i] = std::move( clause2 );
     1678                        stmt = n;
     1679                }
     1680
     1681                if ( stmt->timeout.stmt ) {
     1682                        // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally
     1683                        ast::WaitForStmt::Timeout timeout2;
     1684
     1685                        ast::ptr< ast::Type > target =
     1686                                new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
     1687                        timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
     1688                        timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab );
     1689                        timeout2.stmt = stmt->timeout.stmt->accept( *visitor );
     1690
     1691                        // set results into stmt
     1692                        auto n = mutate( stmt );
     1693                        n->timeout = std::move( timeout2 );
     1694                        stmt = n;
     1695                }
     1696
     1697                if ( stmt->orElse.stmt ) {
     1698                        // resolve the condition like IfStmt, stmts normally
     1699                        ast::WaitForStmt::OrElse orElse2;
     1700
     1701                        orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab );
     1702                        orElse2.stmt = stmt->orElse.stmt->accept( *visitor );
     1703
     1704                        // set results into stmt
     1705                        auto n = mutate( stmt );
     1706                        n->orElse = std::move( orElse2 );
     1707                        stmt = n;
     1708                }
     1709
     1710                return stmt;
    14511711        }
    14521712
     
    14571717                // resolve initialization using the possibilities as determined by the `currentObject`
    14581718                // cursor.
    1459                 ast::Expr * untyped = new ast::UntypedInitExpr{
     1719                ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
    14601720                        singleInit->location, singleInit->value, currentObject.getOptions() };
    1461                 ast::ptr<ast::Expr> newExpr = findKindExpression( untyped, symtab );
     1721                ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
    14621722                const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >();
    14631723
  • src/ResolvExpr/Unify.cc

    rb326277 r6ad19fd  
    11431143                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    11441144                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1145                        ast::OpenVarSet & open, const ast::SymbolTable & symtab
     1146        ) {
     1147                ast::ptr<ast::Type> common;
     1148                return unify( type1, type2, env, need, have, open, symtab, common );
     1149        }
     1150
     1151        bool unify(
     1152                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1153                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    11451154                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
    11461155        ) {
  • src/ResolvExpr/Unify.h

    rb326277 r6ad19fd  
    7272                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    7373                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     74                ast::OpenVarSet & open, const ast::SymbolTable & symtab );
     75
     76        bool unify(
     77                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     78                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    7479                ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
    7580
  • src/ResolvExpr/module.mk

    rb326277 r6ad19fd  
    3535      ResolvExpr/Resolver.cc \
    3636      ResolvExpr/ResolveTypeof.cc \
     37      ResolvExpr/SatisfyAssertions.cpp \
    3738      ResolvExpr/SpecCost.cc \
    3839      ResolvExpr/TypeEnvironment.cc \
Note: See TracChangeset for help on using the changeset viewer.