Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r8e18b8e r0873d22e  
    1717#include <iterator>               // for back_insert_iterator, back_inserter
    1818#include <map>                    // for _Rb_tree_const_iterator, _Rb_tree_i...
     19#include <memory>                 // for unique_ptr
    1920#include <set>                    // for set
    2021#include <string>                 // for string, operator==, operator!=, bas...
    21 #include <utility>                // for pair, move
     22#include <utility>                // for pair
    2223
    2324#include "Common/PassVisitor.h"   // for PassVisitor
     
    9899                findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
    99100
    100                 return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     101                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     102                delete newFirst;
     103                delete newSecond;
     104                return result;
    101105        }
    102106
     
    119123///   newSecond->print( std::cerr );
    120124///   std::cerr << std::endl;
    121                 return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     125                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     126                delete newFirst;
     127                delete newSecond;
     128                return result;
    122129        }
    123130
     
    159166                        return false;
    160167                } // if
    161                 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
    162                         if ( curClass->type ) {
     168                EqvClass curClass;
     169                if ( env.lookup( typeInst->get_name(), curClass ) ) {
     170                        if ( curClass.type ) {
    163171                                Type *common = 0;
    164172                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    165                                 Type* newType = curClass->type->clone();
     173                                std::unique_ptr< Type > newType( curClass.type->clone() );
    166174                                newType->get_qualifiers() = typeInst->get_qualifiers();
    167                                 if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
     175                                if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
    168176                                        if ( common ) {
    169177                                                common->get_qualifiers() = Type::Qualifiers();
    170                                                 EqvClass newClass = *curClass;
    171                                                 newClass.type = common;
    172                                                 env.add( std::move(newClass) );
     178                                                delete curClass.type;
     179                                                curClass.type = common;
     180                                                env.add( curClass );
    173181                                        } // if
    174182                                        return true;
     
    177185                                } // if
    178186                        } else {
    179                                 EqvClass newClass = *curClass;
    180                                 newClass.type = other->clone();
    181                                 newClass.type->get_qualifiers() = Type::Qualifiers();
    182                                 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    183                                 env.add( std::move(newClass) );
     187                                curClass.type = other->clone();
     188                                curClass.type->get_qualifiers() = Type::Qualifiers();
     189                                curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     190                                env.add( curClass );
    184191                        } // if
    185192                } else {
     
    197204        bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    198205                bool result = true;
    199                 const EqvClass *class1 = env.lookup( var1->get_name() );
    200                 const EqvClass *class2 = env.lookup( var2->get_name() );
     206                EqvClass class1, class2;
     207                bool hasClass1 = false, hasClass2 = false;
    201208                bool widen1 = false, widen2 = false;
    202                 Type *type1 = nullptr, *type2 = nullptr;
    203 
    204                 if ( class1 ) {
    205                         if ( class1->type ) {
    206                                 if ( occurs( class1->type, var2->get_name(), env ) ) {
     209                Type *type1 = 0, *type2 = 0;
     210
     211                if ( env.lookup( var1->get_name(), class1 ) ) {
     212                        hasClass1 = true;
     213                        if ( class1.type ) {
     214                                if ( occurs( class1.type, var2->get_name(), env ) ) {
    207215                                        return false;
    208216                                } // if
    209                                 type1 = class1->type->clone();
    210                         } // if
    211                         widen1 = widenMode.widenFirst && class1->allowWidening;
    212                 } // if
    213                 if ( class2 ) {
    214                         if ( class2->type ) {
    215                                 if ( occurs( class2->type, var1->get_name(), env ) ) {
     217                                type1 = class1.type->clone();
     218                        } // if
     219                        widen1 = widenMode.widenFirst && class1.allowWidening;
     220                } // if
     221                if ( env.lookup( var2->get_name(), class2 ) ) {
     222                        hasClass2 = true;
     223                        if ( class2.type ) {
     224                                if ( occurs( class2.type, var1->get_name(), env ) ) {
    216225                                        return false;
    217226                                } // if
    218                                 type2 = class2->type->clone();
    219                         } // if
    220                         widen2 = widenMode.widenSecond && class2->allowWidening;
     227                                type2 = class2.type->clone();
     228                        } // if
     229                        widen2 = widenMode.widenSecond && class2.allowWidening;
    221230                } // if
    222231
     
    226235                        Type *common = 0;
    227236                        if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    228                                 EqvClass newClass1 = *class1;
    229                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    230                                 newClass1.allowWidening = widen1 && widen2;
     237                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     238                                class1.allowWidening = widen1 && widen2;
    231239                                if ( common ) {
    232240                                        common->get_qualifiers() = Type::Qualifiers();
    233                                         newClass1.type = common;
     241                                        delete class1.type;
     242                                        class1.type = common;
    234243                                } // if
    235                                 env.add( std::move(newClass1) );
     244                                env.add( class1 );
    236245                        } else {
    237246                                result = false;
    238247                        } // if
    239                 } else if ( class1 && class2 ) {
     248                } else if ( hasClass1 && hasClass2 ) {
    240249                        if ( type1 ) {
    241                                 EqvClass newClass1 = *class1;
    242                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    243                                 newClass1.allowWidening = widen1;
    244                                 env.add( std::move(newClass1) );
     250                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     251                                class1.allowWidening = widen1;
     252                                env.add( class1 );
    245253                        } else {
    246                                 EqvClass newClass2 = *class2;
    247                                 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
    248                                 newClass2.allowWidening = widen2;
    249                                 env.add( std::move(newClass2) );
    250                         } // if
    251                 } else if ( class1 ) {
    252                         EqvClass newClass1 = *class1;
    253                         newClass1.vars.insert( var2->get_name() );
    254                         newClass1.allowWidening = widen1;
    255                         env.add( std::move(newClass1) );
    256                 } else if ( class2 ) {
    257                         EqvClass newClass2 = *class2;
    258                         newClass2.vars.insert( var1->get_name() );
    259                         newClass2.allowWidening = widen2;
    260                         env.add( std::move(newClass2) );
     254                                class2.vars.insert( class1.vars.begin(), class1.vars.end() );
     255                                class2.allowWidening = widen2;
     256                                env.add( class2 );
     257                        } // if
     258                } else if ( hasClass1 ) {
     259                        class1.vars.insert( var2->get_name() );
     260                        class1.allowWidening = widen1;
     261                        env.add( class1 );
     262                } else if ( hasClass2 ) {
     263                        class2.vars.insert( var1->get_name() );
     264                        class2.allowWidening = widen2;
     265                        env.add( class2 );
    261266                } else {
    262267                        EqvClass newClass;
     
    267272                        env.add( newClass );
    268273                } // if
     274                delete type1;
     275                delete type2;
    269276                return result;
    270277        }
     
    275282                findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
    276283                Type *commonType = 0;
    277                 return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
     284                if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
     285                        if ( commonType ) {
     286                                delete commonType;
     287                        } // if
     288                        return true;
     289                } else {
     290                        return false;
     291                } // if
    278292        }
    279293
     
    469483
    470484        template< typename Iterator, typename Func >
    471         Type* combineTypes( Iterator begin, Iterator end, Func & toType ) {
     485        std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
    472486                std::list< Type * > types;
    473487                for ( ; begin != end; ++begin ) {
     
    475489                        flatten( toType( *begin ), back_inserter( types ) );
    476490                }
    477                 return new TupleType{ Type::Qualifiers(), types };
     491                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
    478492        }
    479493
     
    490504                        if ( isTtype1 && ! isTtype2 ) {
    491505                                // combine all of the things in list2, then unify
    492                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     506                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    493507                        } else if ( isTtype2 && ! isTtype1 ) {
    494508                                // combine all of the things in list1, then unify
    495                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     509                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    496510                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    497511                                return false;
     
    503517                        Type * t1 = (*list1Begin)->get_type();
    504518                        if ( Tuples::isTtype( t1 ) ) {
    505                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     519                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    506520                        } else return false;
    507521                } else if ( list2Begin != list2End ) {
     
    509523                        Type * t2 = (*list2Begin)->get_type();
    510524                        if ( Tuples::isTtype( t2 ) ) {
    511                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     525                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    512526                        } else return false;
    513527                } else {
     
    525539                void premutate( TypeInstType * ) { visit_children = false; }
    526540                Type * postmutate( TypeInstType * typeInst ) {
    527                         if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
    528                                 // expand ttype parameter into its actual type
    529                                 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {
    530                                         return eqvClass->type->clone();
     541                        EqvClass eqvClass;
     542                        if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
     543                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
     544                                        // expand ttype parameter into its actual type
     545                                        if ( eqvClass.type ) {
     546                                                delete typeInst;
     547                                                return eqvClass.type->clone();
     548                                        }
    531549                                }
    532550                        }
     
    551569                                dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) );
    552570                        }
     571                        delete dcl;
    553572                }
    554573        }
     
    559578                        // flatten the parameter lists for both functions so that tuple structure
    560579                        // doesn't affect unification. Must be a clone so that the types don't change.
    561                         FunctionType* flatFunc = functionType->clone();
    562                         FunctionType* flatOther = otherFunction->clone();
     580                        std::unique_ptr<FunctionType> flatFunc( functionType->clone() );
     581                        std::unique_ptr<FunctionType> flatOther( otherFunction->clone() );
    563582                        flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env );
    564583                        flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env );
     
    701720                        if ( isTtype1 && ! isTtype2 ) {
    702721                                // combine all of the things in list2, then unify
    703                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     722                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    704723                        } else if ( isTtype2 && ! isTtype1 ) {
    705724                                // combine all of the things in list1, then unify
    706                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     725                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    707726                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    708727                                return false;
     
    714733                        Type * t1 = *list1Begin;
    715734                        if ( Tuples::isTtype( t1 ) ) {
    716                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     735                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    717736                        } else return false;
    718737                } else if ( list2Begin != list2End ) {
     
    720739                        Type * t2 = *list2Begin;
    721740                        if ( Tuples::isTtype( t2 ) ) {
    722                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     741                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    723742                        } else return false;
    724743                } else {
     
    729748        void Unify::postvisit(TupleType *tupleType) {
    730749                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    731                         TupleType* flat1 = tupleType->clone();
    732                         TupleType* flat2 = otherTuple->clone();
     750                        std::unique_ptr<TupleType> flat1( tupleType->clone() );
     751                        std::unique_ptr<TupleType> flat2( otherTuple->clone() );
    733752                        std::list<Type *> types1, types2;
    734753
     
    737756                        flat2->acceptMutator( expander );
    738757
    739                         flatten( flat1, back_inserter( types1 ) );
    740                         flatten( flat2, back_inserter( types2 ) );
     758                        flatten( flat1.get(), back_inserter( types1 ) );
     759                        flatten( flat2.get(), back_inserter( types2 ) );
    741760
    742761                        result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, indexer );
Note: See TracChangeset for help on using the changeset viewer.