Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r0873d22e r8e18b8e  
    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
    2019#include <set>                    // for set
    2120#include <string>                 // for string, operator==, operator!=, bas...
    22 #include <utility>                // for pair
     21#include <utility>                // for pair, move
    2322
    2423#include "Common/PassVisitor.h"   // for PassVisitor
     
    9998                findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
    10099
    101                 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    102                 delete newFirst;
    103                 delete newSecond;
    104                 return result;
     100                return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    105101        }
    106102
     
    123119///   newSecond->print( std::cerr );
    124120///   std::cerr << std::endl;
    125                 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    126                 delete newFirst;
    127                 delete newSecond;
    128                 return result;
     121                return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    129122        }
    130123
     
    166159                        return false;
    167160                } // if
    168                 EqvClass curClass;
    169                 if ( env.lookup( typeInst->get_name(), curClass ) ) {
    170                         if ( curClass.type ) {
     161                if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
     162                        if ( curClass->type ) {
    171163                                Type *common = 0;
    172164                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    173                                 std::unique_ptr< Type > newType( curClass.type->clone() );
     165                                Type* newType = curClass->type->clone();
    174166                                newType->get_qualifiers() = typeInst->get_qualifiers();
    175                                 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
     167                                if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
    176168                                        if ( common ) {
    177169                                                common->get_qualifiers() = Type::Qualifiers();
    178                                                 delete curClass.type;
    179                                                 curClass.type = common;
    180                                                 env.add( curClass );
     170                                                EqvClass newClass = *curClass;
     171                                                newClass.type = common;
     172                                                env.add( std::move(newClass) );
    181173                                        } // if
    182174                                        return true;
     
    185177                                } // if
    186178                        } else {
    187                                 curClass.type = other->clone();
    188                                 curClass.type->get_qualifiers() = Type::Qualifiers();
    189                                 curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    190                                 env.add( curClass );
     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) );
    191184                        } // if
    192185                } else {
     
    204197        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 ) {
    205198                bool result = true;
    206                 EqvClass class1, class2;
    207                 bool hasClass1 = false, hasClass2 = false;
     199                const EqvClass *class1 = env.lookup( var1->get_name() );
     200                const EqvClass *class2 = env.lookup( var2->get_name() );
    208201                bool widen1 = false, widen2 = false;
    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 ) ) {
     202                Type *type1 = nullptr, *type2 = nullptr;
     203
     204                if ( class1 ) {
     205                        if ( class1->type ) {
     206                                if ( occurs( class1->type, var2->get_name(), env ) ) {
    215207                                        return false;
    216208                                } // if
    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 ) ) {
     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 ) ) {
    225216                                        return false;
    226217                                } // if
    227                                 type2 = class2.type->clone();
    228                         } // if
    229                         widen2 = widenMode.widenSecond && class2.allowWidening;
     218                                type2 = class2->type->clone();
     219                        } // if
     220                        widen2 = widenMode.widenSecond && class2->allowWidening;
    230221                } // if
    231222
     
    235226                        Type *common = 0;
    236227                        if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    237                                 class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    238                                 class1.allowWidening = widen1 && widen2;
     228                                EqvClass newClass1 = *class1;
     229                                newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
     230                                newClass1.allowWidening = widen1 && widen2;
    239231                                if ( common ) {
    240232                                        common->get_qualifiers() = Type::Qualifiers();
    241                                         delete class1.type;
    242                                         class1.type = common;
     233                                        newClass1.type = common;
    243234                                } // if
    244                                 env.add( class1 );
     235                                env.add( std::move(newClass1) );
    245236                        } else {
    246237                                result = false;
    247238                        } // if
    248                 } else if ( hasClass1 && hasClass2 ) {
     239                } else if ( class1 && class2 ) {
    249240                        if ( type1 ) {
    250                                 class1.vars.insert( class2.vars.begin(), class2.vars.end() );
    251                                 class1.allowWidening = widen1;
    252                                 env.add( class1 );
     241                                EqvClass newClass1 = *class1;
     242                                newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
     243                                newClass1.allowWidening = widen1;
     244                                env.add( std::move(newClass1) );
    253245                        } else {
    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 );
     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) );
    266261                } else {
    267262                        EqvClass newClass;
     
    272267                        env.add( newClass );
    273268                } // if
    274                 delete type1;
    275                 delete type2;
    276269                return result;
    277270        }
     
    282275                findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
    283276                Type *commonType = 0;
    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
     277                return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
    292278        }
    293279
     
    483469
    484470        template< typename Iterator, typename Func >
    485         std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
     471        Type* combineTypes( Iterator begin, Iterator end, Func & toType ) {
    486472                std::list< Type * > types;
    487473                for ( ; begin != end; ++begin ) {
     
    489475                        flatten( toType( *begin ), back_inserter( types ) );
    490476                }
    491                 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
     477                return new TupleType{ Type::Qualifiers(), types };
    492478        }
    493479
     
    504490                        if ( isTtype1 && ! isTtype2 ) {
    505491                                // combine all of the things in list2, then unify
    506                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     492                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    507493                        } else if ( isTtype2 && ! isTtype1 ) {
    508494                                // combine all of the things in list1, then unify
    509                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     495                                return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    510496                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    511497                                return false;
     
    517503                        Type * t1 = (*list1Begin)->get_type();
    518504                        if ( Tuples::isTtype( t1 ) ) {
    519                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     505                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    520506                        } else return false;
    521507                } else if ( list2Begin != list2End ) {
     
    523509                        Type * t2 = (*list2Begin)->get_type();
    524510                        if ( Tuples::isTtype( t2 ) ) {
    525                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     511                                return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    526512                        } else return false;
    527513                } else {
     
    539525                void premutate( TypeInstType * ) { visit_children = false; }
    540526                Type * postmutate( TypeInstType * typeInst ) {
    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                                         }
     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();
    549531                                }
    550532                        }
     
    569551                                dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) );
    570552                        }
    571                         delete dcl;
    572553                }
    573554        }
     
    578559                        // flatten the parameter lists for both functions so that tuple structure
    579560                        // doesn't affect unification. Must be a clone so that the types don't change.
    580                         std::unique_ptr<FunctionType> flatFunc( functionType->clone() );
    581                         std::unique_ptr<FunctionType> flatOther( otherFunction->clone() );
     561                        FunctionType* flatFunc = functionType->clone();
     562                        FunctionType* flatOther = otherFunction->clone();
    582563                        flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env );
    583564                        flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env );
     
    720701                        if ( isTtype1 && ! isTtype2 ) {
    721702                                // combine all of the things in list2, then unify
    722                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     703                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    723704                        } else if ( isTtype2 && ! isTtype1 ) {
    724705                                // combine all of the things in list1, then unify
    725                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     706                                return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    726707                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    727708                                return false;
     
    733714                        Type * t1 = *list1Begin;
    734715                        if ( Tuples::isTtype( t1 ) ) {
    735                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     716                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    736717                        } else return false;
    737718                } else if ( list2Begin != list2End ) {
     
    739720                        Type * t2 = *list2Begin;
    740721                        if ( Tuples::isTtype( t2 ) ) {
    741                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     722                                return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    742723                        } else return false;
    743724                } else {
     
    748729        void Unify::postvisit(TupleType *tupleType) {
    749730                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    750                         std::unique_ptr<TupleType> flat1( tupleType->clone() );
    751                         std::unique_ptr<TupleType> flat2( otherTuple->clone() );
     731                        TupleType* flat1 = tupleType->clone();
     732                        TupleType* flat2 = otherTuple->clone();
    752733                        std::list<Type *> types1, types2;
    753734
     
    756737                        flat2->acceptMutator( expander );
    757738
    758                         flatten( flat1.get(), back_inserter( types1 ) );
    759                         flatten( flat2.get(), back_inserter( types2 ) );
     739                        flatten( flat1, back_inserter( types1 ) );
     740                        flatten( flat2, back_inserter( types2 ) );
    760741
    761742                        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.