Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    ree574a2 rf474e91  
    136136
    137137                return unifyExact(
    138                         newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
     138                        newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );
    139139        }
    140140
     
    173173                env.apply( newFirst );
    174174                env.apply( newSecond );
    175                 reset_qualifiers( newFirst );
    176                 reset_qualifiers( newSecond );
     175                clear_qualifiers( newFirst );
     176                clear_qualifiers( newSecond );
    177177
    178178                return unifyExact(
    179                         newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
     179                        newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );
    180180        }
    181181
     
    700700        }
    701701
    702         class Unify_new final : public ast::WithShortCircuiting {
     702        class Unify_new : public ast::WithShortCircuiting {
    703703                const ast::Type * type2;
    704704                ast::TypeEnvironment & tenv;
     
    720720                void previsit( const ast::Node * ) { visit_children = false; }
    721721               
    722                 void postvisit( const ast::VoidType * ) {
     722                void previsit( const ast::VoidType * ) {
     723                        visit_children = false;
    723724                        result = dynamic_cast< const ast::VoidType * >( type2 );
    724725                }
    725726
    726                 void postvisit( const ast::BasicType * basic ) {
     727                void previsit( const ast::BasicType * basic ) {
     728                        visit_children = false;
    727729                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
    728730                                result = basic->kind == basic2->kind;
     
    730732                }
    731733
    732                 void postvisit( const ast::PointerType * pointer ) {
     734                void previsit( const ast::PointerType * pointer ) {
     735                        visit_children = false;
    733736                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    734737                                result = unifyExact(
    735738                                        pointer->base, pointer2->base, tenv, need, have, open,
    736                                         noWiden(), symtab );
    737                         }
    738                 }
    739 
    740                 void postvisit( const ast::ArrayType * array ) {
     739                                        WidenMode{ false, false }, symtab );
     740                        }
     741                }
     742
     743                void previsit( const ast::ArrayType * array ) {
     744                        visit_children = false;
    741745                        auto array2 = dynamic_cast< const ast::ArrayType * >( type2 );
    742746                        if ( ! array2 ) return;
     
    757761
    758762                        result = unifyExact(
    759                                 array->base, array2->base, tenv, need, have, open, noWiden(),
     763                                array->base, array2->base, tenv, need, have, open, WidenMode{ false, false },
    760764                                symtab );
    761765                }
    762766
    763                 void postvisit( const ast::ReferenceType * ref ) {
     767                void previsit( const ast::ReferenceType * ref ) {
     768                        visit_children = false;
    764769                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    765770                                result = unifyExact(
    766                                         ref->base, ref2->base, tenv, need, have, open, noWiden(),
     771                                        ref->base, ref2->base, tenv, need, have, open, WidenMode{ false, false },
    767772                                        symtab );
    768773                        }
     
    778783                        TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}
    779784
    780                         const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
     785                        const ast::Type * postmutate( const ast::TypeInstType * typeInst ) {
    781786                                if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) {
    782787                                        // expand ttype parameter into its actual type
     
    806811                                        // overloaded on outermost mutex and a mutex function has different
    807812                                        // requirements than a non-mutex function
    808                                         remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
     813                                        t.get_and_mutate()->qualifiers
     814                                                -= ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic;
    809815                                        dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } );
    810816                                }
     
    845851                                        return unifyExact(
    846852                                                t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    847                                                 noWiden(), symtab );
     853                                                WidenMode{ false, false }, symtab );
    848854                                } else if ( ! isTuple1 && isTuple2 ) {
    849855                                        // combine remainder of list1, then unify
    850856                                        return unifyExact(
    851857                                                tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    852                                                 noWiden(), symtab );
     858                                                WidenMode{ false, false }, symtab );
    853859                                }
    854860
    855861                                if ( ! unifyExact(
    856                                         t1, t2, env, need, have, open, noWiden(), symtab )
     862                                        t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )
    857863                                ) return false;
    858864
     
    868874                                return unifyExact(
    869875                                        t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    870                                         noWiden(), symtab );
     876                                        WidenMode{ false, false }, symtab );
    871877                        } else if ( crnt2 != end2 ) {
    872878                                // try unifying empty tuple with ttype
     
    875881                                return unifyExact(
    876882                                        tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    877                                         noWiden(), symtab );
     883                                        WidenMode{ false, false }, symtab );
    878884                        }
    879885
     
    913919
    914920        public:
    915                 void postvisit( const ast::FunctionType * func ) {
     921                void previsit( const ast::FunctionType * func ) {
     922                        visit_children = false;
    916923                        auto func2 = dynamic_cast< const ast::FunctionType * >( type2 );
    917924                        if ( ! func2 ) return;
     
    945952                template< typename RefType >
    946953                const RefType * handleRefType( const RefType * inst, const ast::Type * other ) {
     954                        visit_children = false;
    947955                        // check that the other type is compatible and named the same
    948956                        auto otherInst = dynamic_cast< const RefType * >( other );
     
    10031011
    10041012                                if ( ! unifyExact(
    1005                                                 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
     1013                                                pty, pty2, tenv, need, have, open, WidenMode{ false, false }, symtab ) ) {
    10061014                                        result = false;
    10071015                                        return;
     
    10151023
    10161024        public:
    1017                 void postvisit( const ast::StructInstType * aggrType ) {
     1025                void previsit( const ast::StructInstType * aggrType ) {
    10181026                        handleGenericRefType( aggrType, type2 );
    10191027                }
    10201028
    1021                 void postvisit( const ast::UnionInstType * aggrType ) {
     1029                void previsit( const ast::UnionInstType * aggrType ) {
    10221030                        handleGenericRefType( aggrType, type2 );
    10231031                }
    10241032
    1025                 void postvisit( const ast::EnumInstType * aggrType ) {
     1033                void previsit( const ast::EnumInstType * aggrType ) {
    10261034                        handleRefType( aggrType, type2 );
    10271035                }
    10281036
    1029                 void postvisit( const ast::TraitInstType * aggrType ) {
     1037                void previsit( const ast::TraitInstType * aggrType ) {
    10301038                        handleRefType( aggrType, type2 );
    10311039                }
    10321040
    1033                 void postvisit( const ast::TypeInstType * typeInst ) {
     1041                void previsit( const ast::TypeInstType * typeInst ) {
    10341042                        assert( open.find( typeInst->name ) == open.end() );
    10351043                        handleRefType( typeInst, type2 );
     
    10701078                                        return unifyExact(
    10711079                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1072                                                 noWiden(), symtab );
     1080                                                WidenMode{ false, false }, symtab );
    10731081                                } else if ( ! isTuple1 && isTuple2 ) {
    10741082                                        // combine entirety of list1, then unify
    10751083                                        return unifyExact(
    10761084                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1077                                                 noWiden(), symtab );
     1085                                                WidenMode{ false, false }, symtab );
    10781086                                }
    10791087
    10801088                                if ( ! unifyExact(
    1081                                         t1, t2, env, need, have, open, noWiden(), symtab )
     1089                                        t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )
    10821090                                ) return false;
    10831091
     
    10931101                                return unifyExact(
    10941102                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1095                                                 noWiden(), symtab );
     1103                                                WidenMode{ false, false }, symtab );
    10961104                        } else if ( crnt2 != list2.end() ) {
    10971105                                // try unifying empty tuple with ttype
     
    11021110                                return unifyExact(
    11031111                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1104                                                 noWiden(), symtab );
     1112                                                WidenMode{ false, false }, symtab );
    11051113                        }
    11061114
     
    11091117
    11101118        public:
    1111                 void postvisit( const ast::TupleType * tuple ) {
     1119                void previsit( const ast::TupleType * tuple ) {
     1120                        visit_children = false;
    11121121                        auto tuple2 = dynamic_cast< const ast::TupleType * >( type2 );
    11131122                        if ( ! tuple2 ) return;
     
    11231132                }
    11241133
    1125                 void postvisit( const ast::VarArgsType * ) {
     1134                void previsit( const ast::VarArgsType * ) {
     1135                        visit_children = false;
    11261136                        result = dynamic_cast< const ast::VarArgsType * >( type2 );
    11271137                }
    11281138
    1129                 void postvisit( const ast::ZeroType * ) {
     1139                void previsit( const ast::ZeroType * ) {
     1140                        visit_children = false;
    11301141                        result = dynamic_cast< const ast::ZeroType * >( type2 );
    11311142                }
    11321143
    1133                 void postvisit( const ast::OneType * ) {
     1144                void previsit( const ast::OneType * ) {
     1145                        visit_children = false;
    11341146                        result = dynamic_cast< const ast::OneType * >( type2 );
    11351147                }       
     
    11391151                template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    11401152        };
    1141 
    1142         bool unify(
    1143                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    1144                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1145                         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
    1146         ) {
    1147                 ast::OpenVarSet closed;
    1148                 findOpenVars( type1, open, closed, need, have, FirstClosed );
    1149                 findOpenVars( type2, open, closed, need, have, FirstOpen );
    1150                 return unifyInexact(
    1151                         type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
    1152         }
    11531153
    11541154        bool unifyExact(
     
    11841184
    11851185        bool unifyInexact(
    1186                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
    1187                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    1188                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
    1189                         ast::ptr<ast::Type> & common
     1186                        ast::ptr<ast::Type> & type1, ast::ptr<ast::Type> & type2, ast::TypeEnvironment & env,
     1187                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1188                        WidenMode widen, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
    11901189        ) {
    11911190                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
     
    11941193                // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
    11951194                ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
    1196                 reset_qualifiers( t1 );
    1197                 reset_qualifiers( t2 );
     1195                clear_qualifiers( t1 );
     1196                clear_qualifiers( t2 );
    11981197               
    11991198                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
     
    12021201                        // if exact unification on unqualified types, try to merge qualifiers
    12031202                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
    1204                                 common = type1;
    1205                                 reset_qualifiers( common, q1 | q2 );
     1203                                common.set_and_mutate( type1 )->qualifiers = q1 | q2;
    12061204                                return true;
    12071205                        } else {
     
    12131211
    12141212                        // no exact unification, but common type
    1215                         reset_qualifiers( common, q1 | q2 );
     1213                        common.get_and_mutate()->qualifiers = q1 | q2;
    12161214                        return true;
    12171215                } else {
Note: See TracChangeset for help on using the changeset viewer.