Ignore:
Timestamp:
Sep 21, 2022, 11:02:15 AM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
95dab9e
Parents:
428adbc (diff), 0bd46fd (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' into pthread-emulation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r428adbc r7f6a7c9  
    2828#include "Unify.h"                       // for unifyExact, WidenMode
    2929#include "typeops.h"                     // for isFtype
     30#include "Tuples/Tuples.h"
    3031
    3132// #define DEBUG
     
    675676                ast::TypeEnvironment & tenv;
    676677                const ast::OpenVarSet & open;
     678                ast::AssertionSet & need;
     679                ast::AssertionSet & have;
    677680        public:
    678681                static size_t traceId;
     
    681684                CommonType_new(
    682685                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
    683                         ast::TypeEnvironment & env, const ast::OpenVarSet & o )
    684                 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
     686                        ast::TypeEnvironment & env, const ast::OpenVarSet & o,
     687                        ast::AssertionSet & need, ast::AssertionSet & have )
     688                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {}
    685689
    686690                void previsit( const ast::Node * ) { visit_children = false; }
     
    753757                bool tryResolveWithTypedEnum( const ast::Type * type1 ) {
    754758                        if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {
    755                                 ast::AssertionSet have, need; // unused
    756759                                ast::OpenVarSet newOpen{ open };
    757760                                if (enumInst->base->base
     
    792795                                        reset_qualifiers( t2 );
    793796
    794                                         ast::AssertionSet have, need;
    795797                                        ast::OpenVarSet newOpen{ open };
    796798                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     
    803805                                                }
    804806                                        }
     807                                        else if ( isFtype (t1) && isFtype (t2) ) {
     808                                                auto f1 = t1.as<ast::FunctionType>();
     809                                                if (!f1) return;
     810                                                auto f2 = t2.strict_as<ast::FunctionType>();
     811
     812                                                assertf(f1->returns.size() <= 1, "Function return should not be a list");
     813                                                assertf(f2->returns.size() <= 1, "Function return should not be a list");
     814
     815                                                if (
     816                                                        ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() )
     817                                                        && ! f1->isTtype()
     818                                                        && ! f2->isTtype()
     819                                                ) return;
     820
     821                                                auto params1 = flattenList( f1->params, tenv );
     822                                                auto params2 = flattenList( f2->params, tenv );
     823
     824                                                auto crnt1 = params1.begin();
     825                                                auto crnt2 = params2.begin();
     826                                                auto end1 = params1.end();
     827                                                auto end2 = params2.end();
     828
     829                                                while (crnt1 != end1 && crnt2 != end2 ) {
     830                                                        const ast::Type * arg1 = *crnt1;
     831                                                        const ast::Type * arg2 = *crnt2;
     832
     833                                                        bool isTuple1 = Tuples::isTtype( t1 );
     834                                                        bool isTuple2 = Tuples::isTtype( t2 );
     835
     836                                                        // assumes here that ttype *must* be last parameter
     837                                                        if ( isTuple1 && ! isTuple2 ) {
     838                                                                // combine remainder of list2, then unify
     839                                                                if (unifyExact(
     840                                                                        arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
     841                                                                        noWiden(), symtab )) {
     842                                                                                break;
     843
     844                                                                }
     845                                                                else return;
     846                                                        } else if ( ! isTuple1 && isTuple2 ) {
     847                                                                // combine remainder of list1, then unify
     848                                                                if (unifyExact(
     849                                                                        tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open,
     850                                                                        noWiden(), symtab )) {
     851                                                                                break;
     852
     853                                                                }
     854                                                                else return;
     855                                                        }
     856
     857                                                        // allow qualifiers of pointer and reference base to become more specific
     858                                                        if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) {
     859                                                                if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) {
     860                                                                        ast::ptr<ast::Type> base1 = ref1->base;
     861                                                                        ast::ptr<ast::Type> base2 = ref2->base;
     862
     863                                                                        // xxx - assume LHS is always the target type
     864
     865                                                                        if ( ! ((widen.second && ref2->qualifiers.is_mutex)
     866                                                                        || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return;
     867
     868                                                                        if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
     869
     870                                                                                reset_qualifiers(base1);
     871                                                                                reset_qualifiers(base2);
     872
     873                                                                                if ( ! unifyExact(
     874                                                                                        base1, base2, tenv, need, have, open, noWiden(), symtab )
     875                                                                                ) return;
     876                                                                        }       
     877                                                                }
     878                                                                else return;
     879                                                        }
     880                                                        else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) {
     881                                                                if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) {
     882                                                                        ast::ptr<ast::Type> base1 = ptr1->base;
     883                                                                        ast::ptr<ast::Type> base2 = ptr2->base;
     884
     885                                                                        // xxx - assume LHS is always the target type
     886                                                                        // a function accepting const can always be called by non-const arg
     887
     888                                                                        if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) {
     889
     890                                                                                reset_qualifiers(base1);
     891                                                                                reset_qualifiers(base2);
     892
     893                                                                                if ( ! unifyExact(
     894                                                                                        base1, base2, tenv, need, have, open, noWiden(), symtab )
     895                                                                                ) return;
     896                                                                        }       
     897                                                                }
     898                                                                else return;
     899
     900                                                        }
     901                                                        else if (! unifyExact(
     902                                                                arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return;
     903
     904                                                        ++crnt1; ++crnt2;
     905                                                }
     906                                                if ( crnt1 != end1 ) {
     907                                                        // try unifying empty tuple with ttype
     908                                                        const ast::Type * t1 = *crnt1;
     909                                                        if (! Tuples::isTtype( t1 ) ) return;
     910                                                        if (! unifyExact(
     911                                                                t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open,
     912                                                                noWiden(), symtab )) return;
     913                                                } else if ( crnt2 != end2 ) {
     914                                                        // try unifying empty tuple with ttype
     915                                                        const ast::Type * t2 = *crnt2;
     916                                                        if (! Tuples::isTtype( t2 ) ) return;
     917                                                        if (! unifyExact(
     918                                                                tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open,
     919                                                                noWiden(), symtab )) return;
     920                                                }
     921                                                if ((f1->returns.size() == 0 && f2->returns.size() == 0)
     922                                                  || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) {
     923                                                        result = pointer;
     924
     925                                                        for (auto & assn : f1->assertions) {
     926                                                                auto i = need.find(assn);
     927                                                                if (i != need.end()) i->second.isUsed = true;
     928                                                                auto j = have.find(assn);
     929                                                                if (j != have.end()) j->second.isUsed = true;
     930                                                        }
     931
     932                                                        for (auto & assn : f2->assertions) {
     933                                                                auto i = need.find(assn);
     934                                                                if (i != need.end()) i->second.isUsed = true;
     935                                                                auto j = have.find(assn);
     936                                                                if (j != have.end()) j->second.isUsed = true;
     937                                                        }
     938
     939                                                }
     940                                        } // if ftype
     941                                       
    805942                                }
    806943                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     
    839976                                        reset_qualifiers( t2 );
    840977
    841                                         ast::AssertionSet have, need;
    842978                                        ast::OpenVarSet newOpen{ open };
    843979                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     
    857993                                // xxx - does unifying a ref with typed enumInst makes sense?
    858994                                if (!dynamic_cast<const ast::EnumInstType *>(type2))
    859                                         result = commonType( type2, ref, widen, symtab, tenv, open );
     995                                        result = commonType( type2, ref, tenv, need, have, open, widen, symtab );
    860996                        }
    861997                }
     
    8771013                        // xxx - is this already handled by unify?
    8781014                        if (!dynamic_cast<const ast::EnumInstType *>(type2))
    879                                 result = commonType( type2, enumInst, widen, symtab, tenv, open );
     1015                                result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab);
    8801016                }
    8811017
     
    8951031                                        reset_qualifiers( t2 );
    8961032
    897                                         ast::AssertionSet have, need;
    8981033                                        ast::OpenVarSet newOpen{ open };
    8991034                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     
    9991134        ast::ptr< ast::Type > commonType(
    10001135                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
    1001                         WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
    1002                         const ast::OpenVarSet & open
     1136                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1137                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab
    10031138        ) {
    10041139                unsigned depth1 = type1->referenceDepth();
     
    10361171                }
    10371172                // otherwise both are reference types of the same depth and this is handled by the visitor
    1038                 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };
     1173                ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open, need, have };
    10391174                type1->accept( visitor );
    10401175                ast::ptr< ast::Type > result = visitor.core.result;
     
    10471182                                        if ( type->base ) {
    10481183                                                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
    1049                                                 ast::AssertionSet have, need;
    10501184                                                ast::OpenVarSet newOpen{ open };
    10511185
Note: See TracChangeset for help on using the changeset viewer.