Changeset c76bd34 for src/ResolvExpr


Ignore:
Timestamp:
Oct 7, 2020, 4:31:43 PM (5 years ago)
Author:
Colby Alexander Parsons <caparsons@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
848439f
Parents:
ae2c27a (diff), 597c5d18 (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 into master

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    rae2c27a rc76bd34  
    188188
    189189                        // mark conversion cost and also specialization cost of param type
    190                         const ast::Type * paramType = (*param)->get_type();
     190                        // const ast::Type * paramType = (*param)->get_type();
    191191                        cand->expr = ast::mutate_field_index(
    192192                                appExpr, &ast::ApplicationExpr::args, i,
    193193                                computeExpressionConversionCost(
    194                                         args[i], paramType, symtab, cand->env, convCost ) );
    195                         convCost.decSpec( specCost( paramType ) );
     194                                        args[i], *param, symtab, cand->env, convCost ) );
     195                        convCost.decSpec( specCost( *param ) );
    196196                        ++param;  // can't be in for-loop update because of the continue
    197197                }
     
    698698                        if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) {
    699699                                // attempt to narrow based on expected target type
    700                                 const ast::Type * returnType = funcType->returns.front()->get_type();
     700                                const ast::Type * returnType = funcType->returns.front();
    701701                                if ( ! unify(
    702702                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
     
    712712                        std::size_t genStart = 0;
    713713
    714                         for ( const ast::DeclWithType * param : funcType->params ) {
    715                                 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
     714                        // xxx - how to handle default arg after change to ftype representation?
     715                        if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) {
     716                                if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) {
     717                                        // function may have default args only if directly calling by name
     718                                        // must use types on candidate however, due to RenameVars substitution
     719                                        auto nParams = funcType->params.size();
     720
     721                                        for (size_t i=0; i<nParams; ++i) {
     722                                                auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
     723                                                if (!instantiateArgument(
     724                                                        funcType->params[i], obj->init, args, results, genStart, symtab)) return;
     725                                        }
     726                                        goto endMatch;
     727                                }
     728                        }
     729                        for ( const auto & param : funcType->params ) {
    716730                                // Try adding the arguments corresponding to the current parameter to the existing
    717731                                // matches
     732                                // no default args for indirect calls
    718733                                if ( ! instantiateArgument(
    719                                         obj->type, obj->init, args, results, genStart, symtab ) ) return;
    720                         }
    721 
     734                                        param, nullptr, args, results, genStart, symtab ) ) return;
     735                        }
     736
     737                        endMatch:
    722738                        if ( funcType->isVarArgs ) {
    723739                                // append any unused arguments to vararg pack
     
    816832                /// Adds aggregate member interpretations
    817833                void addAggMembers(
    818                         const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
     834                        const ast::BaseInstType * aggrInst, const ast::Expr * expr,
    819835                        const Candidate & cand, const Cost & addedCost, const std::string & name
    820836                ) {
     
    12631279
    12641280                void postvisit( const ast::UntypedOffsetofExpr * offsetofExpr ) {
    1265                         const ast::ReferenceToType * aggInst;
     1281                        const ast::BaseInstType * aggInst;
    12661282                        if (( aggInst = offsetofExpr->type.as< ast::StructInstType >() )) ;
    12671283                        else if (( aggInst = offsetofExpr->type.as< ast::UnionInstType >() )) ;
  • src/ResolvExpr/ConversionCost.cc

    rae2c27a rc76bd34  
    520520                return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
    521521        } else {
    522                 ast::Pass<ConversionCost_new> converter( dst, srcIsLvalue, symtab, env, localConversionCost );
    523                 src->accept( converter );
    524                 return converter.core.cost;
     522                return ast::Pass<ConversionCost_new>::read( src, dst, srcIsLvalue, symtab, env, localConversionCost );
    525523        }
    526524}
     
    563561                        }
    564562                } else {
    565                         ast::Pass<ConversionCost_new> converter( dst, srcIsLvalue, symtab, env, localConversionCost );
    566                         src->accept( converter );
    567                         return converter.core.cost;
     563                        return ast::Pass<ConversionCost_new>::read( src, dst, srcIsLvalue, symtab, env, localConversionCost );
    568564                }
    569565        } else {
  • src/ResolvExpr/ConversionCost.h

    rae2c27a rc76bd34  
    8888        static size_t traceId;
    8989        Cost cost;
     90        Cost result() { return cost; }
    9091
    9192        ConversionCost_new( const ast::Type * dst, bool srcIsLvalue, const ast::SymbolTable & symtab,
  • src/ResolvExpr/CurrentObject.cc

    rae2c27a rc76bd34  
    594594        class SimpleIterator final : public MemberIterator {
    595595                CodeLocation location;
    596                 readonly< Type > type = nullptr;
     596                const Type * type = nullptr;
    597597        public:
    598598                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
     
    630630        class ArrayIterator final : public MemberIterator {
    631631                CodeLocation location;
    632                 readonly< ArrayType > array = nullptr;
    633                 readonly< Type > base = nullptr;
     632                const ArrayType * array = nullptr;
     633                const Type * base = nullptr;
    634634                size_t index = 0;
    635635                size_t size = 0;
     
    923923
    924924        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) {
    925                 if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) {
     925                if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) {
    926926                        if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) {
    927927                                return new StructIterator{ loc, sit };
     
    932932                                        dynamic_cast< const EnumInstType * >( type )
    933933                                                || dynamic_cast< const TypeInstType * >( type ),
    934                                         "Encountered unhandled ReferenceToType in createMemberIterator: %s",
     934                                        "Encountered unhandled BaseInstType in createMemberIterator: %s",
    935935                                                toString( type ).c_str() );
    936936                                return new SimpleIterator{ loc, type };
     
    965965                                        DesignatorChain & d = *dit;
    966966                                        PRINT( std::cerr << "____actual: " << t << std::endl; )
    967                                         if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) {
     967                                        if ( auto refType = dynamic_cast< const BaseInstType * >( t ) ) {
    968968                                                // concatenate identical field names
    969969                                                for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
  • src/ResolvExpr/Resolver.cc

    rae2c27a rc76bd34  
    3838#include "Common/PassVisitor.h"          // for PassVisitor
    3939#include "Common/SemanticError.h"        // for SemanticError
     40#include "Common/Stats/ResolveTime.h"    // for ResolveTime::start(), ResolveTime::stop()
    4041#include "Common/utility.h"              // for ValueGuard, group_iterate
    4142#include "InitTweak/GenInit.h"
     
    965966                /// Finds deleted expressions in an expression tree
    966967                struct DeleteFinder_new final : public ast::WithShortCircuiting {
    967                         const ast::DeletedExpr * delExpr = nullptr;
     968                        const ast::DeletedExpr * result = nullptr;
    968969
    969970                        void previsit( const ast::DeletedExpr * expr ) {
    970                                 if ( delExpr ) { visit_children = false; }
    971                                 else { delExpr = expr; }
     971                                if ( result ) { visit_children = false; }
     972                                else { result = expr; }
    972973                        }
    973974
    974975                        void previsit( const ast::Expr * ) {
    975                                 if ( delExpr ) { visit_children = false; }
     976                                if ( result ) { visit_children = false; }
    976977                        }
    977978                };
     
    980981        /// Check if this expression is or includes a deleted expression
    981982        const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
    982                 ast::Pass<DeleteFinder_new> finder;
    983                 expr->accept( finder );
    984                 return finder.core.delExpr;
     983                return ast::Pass<DeleteFinder_new>::read( expr );
    985984        }
    986985
     
    11711170                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11721171                ) {
    1173                         return findKindExpression( untyped, symtab );
     1172                        Stats::ResolveTime::start( untyped );
     1173                        auto res = findKindExpression( untyped, symtab );
     1174                        Stats::ResolveTime::stop();
     1175                        return res;
    11741176                }
    11751177        } // anonymous namespace
     
    12211223                template<typename Iter>
    12221224                inline bool nextMutex( Iter & it, const Iter & end ) {
    1223                         while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1225                        while ( it != end && ! (*it)->is_mutex() ) { ++it; }
    12241226                        return it != end;
    12251227                }
     
    12611263                const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
    12621264                const ast::CatchStmt *       previsit( const ast::CatchStmt * );
     1265                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12631266                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
    12641267
     
    14931496
    14941497        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    1495                 // TODO: This will need a fix for the decl/cond scoping problem.
     1498                // Until we are very sure this invarent (ifs that move between passes have thenPart)
     1499                // holds, check it. This allows a check for when to decode the mangling.
     1500                if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) {
     1501                        assert( ifStmt->thenPart );
     1502                }
     1503                // Encode the catchStmt so the condition can see the declaration.
    14961504                if ( catchStmt->cond ) {
    1497                         ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1498                         catchStmt = ast::mutate_field(
    1499                                 catchStmt, &ast::CatchStmt::cond,
    1500                                 findSingleExpression( catchStmt->cond, boolType, symtab ) );
     1505                        ast::CatchStmt * stmt = mutate( catchStmt );
     1506                        stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body );
     1507                        stmt->cond = nullptr;
     1508                        return stmt;
     1509                }
     1510                return catchStmt;
     1511        }
     1512
     1513        const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) {
     1514                // Decode the catchStmt so everything is stored properly.
     1515                const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>();
     1516                if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) {
     1517                        assert( ifStmt->cond );
     1518                        assert( ifStmt->elsePart );
     1519                        ast::CatchStmt * stmt = ast::mutate( catchStmt );
     1520                        stmt->cond = ifStmt->cond;
     1521                        stmt->body = ifStmt->elsePart;
     1522                        // ifStmt should be implicately deleted here.
     1523                        return stmt;
    15011524                }
    15021525                return catchStmt;
     
    16151638                                                                // Check if the argument matches the parameter type in the current
    16161639                                                                // scope
    1617                                                                 ast::ptr< ast::Type > paramType = (*param)->get_type();
     1640                                                                // ast::ptr< ast::Type > paramType = (*param)->get_type();
    16181641                                                                if (
    16191642                                                                        ! unify(
    1620                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
     1643                                                                                arg->expr->result, *param, resultEnv, need, have, open,
    16211644                                                                                symtab )
    16221645                                                                ) {
     
    16251648                                                                        ss << "candidate function not viable: no known conversion "
    16261649                                                                                "from '";
    1627                                                                         ast::print( ss, (*param)->get_type() );
     1650                                                                        ast::print( ss, *param );
    16281651                                                                        ss << "' to '";
    16291652                                                                        ast::print( ss, arg->expr->result );
  • src/ResolvExpr/SatisfyAssertions.cpp

    rae2c27a rc76bd34  
    318318                                        if ( ! func ) continue;
    319319
    320                                         for ( const ast::DeclWithType * param : func->params ) {
    321                                                 cost.decSpec( specCost( param->get_type() ) );
     320                                        for ( const auto & param : func->params ) {
     321                                                cost.decSpec( specCost( param ) );
    322322                                        }
    323323
  • src/ResolvExpr/SpecCost.cc

    rae2c27a rc76bd34  
    178178                void previsit( const ast::FunctionType * fty ) {
    179179                        int minCount = std::numeric_limits<int>::max();
    180                         updateMinimumPresent( minCount, fty->params, decl_type );
    181                         updateMinimumPresent( minCount, fty->returns, decl_type );
     180                        updateMinimumPresent( minCount, fty->params, type_deref );
     181                        updateMinimumPresent( minCount, fty->returns, type_deref );
    182182                        // Add another level to minCount if set.
    183183                        count = toNoneOrInc( minCount );
  • src/ResolvExpr/Unify.cc

    rae2c27a rc76bd34  
    395395
    396396        template< typename Iterator1, typename Iterator2 >
    397         bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     397        bool unifyTypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    398398                auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
    399399                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     
    489489                                        || flatOther->isTtype()
    490490                        ) {
    491                                 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    492                                         if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     491                                if ( unifyTypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     492                                        if ( unifyTypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    493493
    494494                                                // the original types must be used in mark assertions, since pointer comparisons are used
     
    784784
    785785                /// returns flattened version of `src`
    786                 static std::vector< ast::ptr< ast::DeclWithType > > flattenList(
    787                         const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env
     786                static std::vector< ast::ptr< ast::Type > > flattenList(
     787                        const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
    788788                ) {
    789                         std::vector< ast::ptr< ast::DeclWithType > > dst;
     789                        std::vector< ast::ptr< ast::Type > > dst;
    790790                        dst.reserve( src.size() );
    791                         for ( const ast::DeclWithType * d : src ) {
     791                        for ( const auto & d : src ) {
    792792                                ast::Pass<TtypeExpander_new> expander{ env };
    793793                                // TtypeExpander pass is impure (may mutate nodes in place)
    794794                                // need to make nodes shared to prevent accidental mutation
    795                                 ast::ptr<ast::DeclWithType> dc = d->accept(expander);
    796                                 auto types = flatten( dc->get_type() );
     795                                ast::ptr<ast::Type> dc = d->accept(expander);
     796                                auto types = flatten( dc );
    797797                                for ( ast::ptr< ast::Type > & t : types ) {
    798798                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play
     
    803803                                        // requirements than a non-mutex function
    804804                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
    805                                         dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } );
     805                                        dst.emplace_back( t );
    806806                                }
    807807                        }
     
    811811                /// Creates a tuple type based on a list of DeclWithType
    812812                template< typename Iter >
    813                 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) {
     813                static ast::ptr< ast::Type > tupleFromTypes( Iter crnt, Iter end ) {
    814814                        std::vector< ast::ptr< ast::Type > > types;
    815815                        while ( crnt != end ) {
    816816                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    817817                                // that this results in a flat tuple
    818                                 flatten( (*crnt)->get_type(), types );
     818                                flatten( *crnt, types );
    819819
    820820                                ++crnt;
     
    825825
    826826                template< typename Iter >
    827                 static bool unifyDeclList(
     827                static bool unifyTypeList(
    828828                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    829829                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     
    831831                ) {
    832832                        while ( crnt1 != end1 && crnt2 != end2 ) {
    833                                 const ast::Type * t1 = (*crnt1)->get_type();
    834                                 const ast::Type * t2 = (*crnt2)->get_type();
     833                                const ast::Type * t1 = *crnt1;
     834                                const ast::Type * t2 = *crnt2;
    835835                                bool isTuple1 = Tuples::isTtype( t1 );
    836836                                bool isTuple2 = Tuples::isTtype( t2 );
     
    840840                                        // combine remainder of list2, then unify
    841841                                        return unifyExact(
    842                                                 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     842                                                t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    843843                                                noWiden(), symtab );
    844844                                } else if ( ! isTuple1 && isTuple2 ) {
    845845                                        // combine remainder of list1, then unify
    846846                                        return unifyExact(
    847                                                 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     847                                                tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    848848                                                noWiden(), symtab );
    849849                                }
     
    860860                        if ( crnt1 != end1 ) {
    861861                                // try unifying empty tuple with ttype
    862                                 const ast::Type * t1 = (*crnt1)->get_type();
     862                                const ast::Type * t1 = *crnt1;
    863863                                if ( ! Tuples::isTtype( t1 ) ) return false;
    864864                                return unifyExact(
    865                                         t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     865                                        t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    866866                                        noWiden(), symtab );
    867867                        } else if ( crnt2 != end2 ) {
    868868                                // try unifying empty tuple with ttype
    869                                 const ast::Type * t2 = (*crnt2)->get_type();
     869                                const ast::Type * t2 = *crnt2;
    870870                                if ( ! Tuples::isTtype( t2 ) ) return false;
    871871                                return unifyExact(
    872                                         tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     872                                        tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    873873                                        noWiden(), symtab );
    874874                        }
     
    877877                }
    878878
    879                 static bool unifyDeclList(
    880                         const std::vector< ast::ptr< ast::DeclWithType > > & list1,
    881                         const std::vector< ast::ptr< ast::DeclWithType > > & list2,
     879                static bool unifyTypeList(
     880                        const std::vector< ast::ptr< ast::Type > > & list1,
     881                        const std::vector< ast::ptr< ast::Type > > & list2,
    882882                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    883883                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    884884                ) {
    885                         return unifyDeclList(
     885                        return unifyTypeList(
    886886                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
    887887                                symtab );
     
    928928                        ) return;
    929929
    930                         if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
    931                         if ( ! unifyDeclList(
     930                        if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
     931                        if ( ! unifyTypeList(
    932932                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    933933
     
    12321232        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {
    12331233                if ( func->returns.empty() ) return new ast::VoidType{};
    1234                 if ( func->returns.size() == 1 ) return func->returns[0]->get_type();
     1234                if ( func->returns.size() == 1 ) return func->returns[0];
    12351235
    12361236                std::vector<ast::ptr<ast::Type>> tys;
    1237                 for ( const ast::DeclWithType * decl : func->returns ) {
    1238                         tys.emplace_back( decl->get_type() );
     1237                for ( const auto & decl : func->returns ) {
     1238                        tys.emplace_back( decl );
    12391239                }
    12401240                return new ast::TupleType{ std::move(tys) };
Note: See TracChangeset for help on using the changeset viewer.