Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r00ac42e r0873d22e  
    2020#include <set>                    // for set
    2121#include <string>                 // for string, operator==, operator!=, bas...
    22 #include <utility>                // for pair, move
     22#include <utility>                // for pair
    2323
    2424#include "Common/PassVisitor.h"   // for PassVisitor
     
    166166                        return false;
    167167                } // if
    168                 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
    169                         if ( curClass->type ) {
     168                EqvClass curClass;
     169                if ( env.lookup( typeInst->get_name(), curClass ) ) {
     170                        if ( curClass.type ) {
    170171                                Type *common = 0;
    171172                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    172                                 std::unique_ptr< Type > newType( curClass->type->clone() );
     173                                std::unique_ptr< Type > newType( curClass.type->clone() );
    173174                                newType->get_qualifiers() = typeInst->get_qualifiers();
    174                                 if ( unifyInexact( newType.get(), 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 ) ) {
    175176                                        if ( common ) {
    176177                                                common->get_qualifiers() = Type::Qualifiers();
    177                                                 env.add( EqvClass{ *curClass, common } );
     178                                                delete curClass.type;
     179                                                curClass.type = common;
     180                                                env.add( curClass );
    178181                                        } // if
    179182                                        return true;
     
    182185                                } // if
    183186                        } else {
    184                                 EqvClass newClass { *curClass, other };
    185                                 newClass.type->get_qualifiers() = Type::Qualifiers();
    186                                 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    187                                 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 );
    188191                        } // if
    189192                } else {
     
    201204        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 ) {
    202205                bool result = true;
    203                 const EqvClass *class1 = env.lookup( var1->get_name() );
    204                 const EqvClass *class2 = env.lookup( var2->get_name() );
     206                EqvClass class1, class2;
     207                bool hasClass1 = false, hasClass2 = false;
    205208                bool widen1 = false, widen2 = false;
    206                 Type *type1 = nullptr, *type2 = nullptr;
    207 
    208                 if ( class1 ) {
    209                         if ( class1->type ) {
    210                                 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 ) ) {
    211215                                        return false;
    212216                                } // if
    213                                 type1 = class1->type->clone();
    214                         } // if
    215                         widen1 = widenMode.widenFirst && class1->allowWidening;
    216                 } // if
    217                 if ( class2 ) {
    218                         if ( class2->type ) {
    219                                 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 ) ) {
    220225                                        return false;
    221226                                } // if
    222                                 type2 = class2->type->clone();
    223                         } // if
    224                         widen2 = widenMode.widenSecond && class2->allowWidening;
     227                                type2 = class2.type->clone();
     228                        } // if
     229                        widen2 = widenMode.widenSecond && class2.allowWidening;
    225230                } // if
    226231
     
    230235                        Type *common = 0;
    231236                        if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    232                                 EqvClass newClass1 = *class1;
    233                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    234                                 newClass1.allowWidening = widen1 && widen2;
     237                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     238                                class1.allowWidening = widen1 && widen2;
    235239                                if ( common ) {
    236240                                        common->get_qualifiers() = Type::Qualifiers();
    237                                         delete newClass1.type;
    238                                         newClass1.type = common;
     241                                        delete class1.type;
     242                                        class1.type = common;
    239243                                } // if
    240                                 env.add( std::move(newClass1) );
     244                                env.add( class1 );
    241245                        } else {
    242246                                result = false;
    243247                        } // if
    244                 } else if ( class1 && class2 ) {
     248                } else if ( hasClass1 && hasClass2 ) {
    245249                        if ( type1 ) {
    246                                 EqvClass newClass1 = *class1;
    247                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    248                                 newClass1.allowWidening = widen1;
    249                                 env.add( std::move(newClass1) );
     250                                class1.vars.insert( class2.vars.begin(), class2.vars.end() );
     251                                class1.allowWidening = widen1;
     252                                env.add( class1 );
    250253                        } else {
    251                                 EqvClass newClass2 = *class2;
    252                                 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
    253                                 newClass2.allowWidening = widen2;
    254                                 env.add( std::move(newClass2) );
    255                         } // if
    256                 } else if ( class1 ) {
    257                         EqvClass newClass1 = *class1;
    258                         newClass1.vars.insert( var2->get_name() );
    259                         newClass1.allowWidening = widen1;
    260                         env.add( std::move(newClass1) );
    261                 } else if ( class2 ) {
    262                         EqvClass newClass2 = *class2;
    263                         newClass2.vars.insert( var1->get_name() );
    264                         newClass2.allowWidening = widen2;
    265                         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 );
    266266                } else {
    267267                        EqvClass newClass;
     
    539539                void premutate( TypeInstType * ) { visit_children = false; }
    540540                Type * postmutate( TypeInstType * typeInst ) {
    541                         if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
    542                                 // expand ttype parameter into its actual type
    543                                 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {
    544                                         delete typeInst;
    545                                         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                                        }
    546549                                }
    547550                        }
Note: See TracChangeset for help on using the changeset viewer.