Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r1cbca6e r721f17a  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Sep 02 14:43:22 2015
    13 // Update Count     : 36
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Jun 26 14:57:05 2015
     13// Update Count     : 7
    1414//
    1515
     
    2828
    2929
    30 // #define DEBUG
     30//#define DEBUG
    3131
    3232namespace ResolvExpr {
     
    7373        };
    7474
    75         /// Attempts an inexact unification of type1 and type2.
    76         /// Returns false if no such unification; if the types can be unified, sets common (unless they unify exactly and have identical type qualifiers)
    7775        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    7876        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     
    8078        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    8179                TypeEnvironment newEnv;
    82                 OpenVarSet openVars, closedVars; // added closedVars
     80                OpenVarSet openVars;
    8381                AssertionSet needAssertions, haveAssertions;
    8482                Type *newFirst = first->clone(), *newSecond = second->clone();
    8583                env.apply( newFirst );
    8684                env.apply( newSecond );
    87 
    88                 // do we need to do this? Seems like we do, types should be able to be compatible if they
    89                 // have free variables that can unify
    90                 findOpenVars( newFirst, openVars, closedVars, needAssertions, haveAssertions, false );
    91                 findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
    92 
    9385                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    9486                delete newFirst;
     
    156148                        if ( curClass.type ) {
    157149                                Type *common = 0;
    158                                 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    159150                                std::auto_ptr< Type > newType( curClass.type->clone() );
    160151                                newType->get_qualifiers() = typeInst->get_qualifiers();
     
    289280                TypeEnvironment debugEnv( env );
    290281#endif
    291                 if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
    292                         return false;
    293                 }
    294 
    295282                bool result;
    296283                TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
     
    305292                bool isopen1 = var1 && ( entry1 != openVars.end() );
    306293                bool isopen2 = var2 && ( entry2 != openVars.end() );
    307 
    308                 if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
     294                if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
     295                        return false;
     296                } else if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    309297                        result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    310298                } else if ( isopen1 ) {
     
    431419
    432420        void Unify::visit(ArrayType *arrayType) {
     421                // XXX -- compare array dimension
    433422                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    434                 // to unify, array types must both be VLA or both not VLA
    435                 // and must both have a dimension expression or not have a dimension
    436                 if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen()
    437                                 && ((arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0)
    438                                         || (arrayType->get_dimension() == 0 && otherArray->get_dimension() == 0))) {
    439 
    440                         // not positive this is correct in all cases, but it's needed for typedefs
    441                         if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {
    442                                 return;
    443                         }
    444 
    445                         if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() &&
    446                                 arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0 ) {
    447                                 ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
    448                                 ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( otherArray->get_dimension() );
    449                                 assert(ce1 && ce2);
    450 
    451                                 Constant * c1 = ce1->get_constant();
    452                                 Constant * c2 = ce2->get_constant();
    453 
    454                                 if ( c1->get_value() != c2->get_value() ) {
    455                                         // does not unify if the dimension is different
    456                                         return;
    457                                 }
    458                         }
    459 
     423                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    460424                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    461425                } // if
     
    465429        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    466430                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    467                         // Type * commonType;
    468                         // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    469431                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    470432                                return false;
     
    481443                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    482444                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    483 
     445 
    484446                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    485447       
Note: See TracChangeset for help on using the changeset viewer.