Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r02ec390 rf5234f3  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 26 14:57:05 2015
    13 // Update Count     : 7
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Sep 02 14:43:22 2015
     13// Update Count     : 36
    1414//
    1515
     
    2828
    2929
    30 //#define DEBUG
     30// #define DEBUG
    3131
    3232namespace ResolvExpr {
     
    8181        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    8282                TypeEnvironment newEnv;
    83                 OpenVarSet openVars;
     83                OpenVarSet openVars, closedVars; // added closedVars
    8484                AssertionSet needAssertions, haveAssertions;
    8585                Type *newFirst = first->clone(), *newSecond = second->clone();
    8686                env.apply( newFirst );
    8787                env.apply( newSecond );
     88
     89                // do we need to do this? Seems like we do, types should be able to be compatible if they
     90                // have free variables that can unify
     91                findOpenVars( newFirst, openVars, closedVars, needAssertions, haveAssertions, false );
     92                findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
     93
    8894                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    8995                delete newFirst;
     
    426432
    427433        void Unify::visit(ArrayType *arrayType) {
    428                 // XXX -- compare array dimension
    429434                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    430                 if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
     435                // to unify, array types must both be VLA or both not VLA
     436                // and must both have a dimension expression or not have a dimension
     437                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen()
     438                                && ((arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0)
     439                                        || (arrayType->get_dimension() == 0 && otherArray->get_dimension() == 0))) {
     440
     441                        // not positive this is correct in all cases, but it's needed for typedefs
     442                        if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {
     443                                return;
     444                        }
     445
     446                        if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() &&
     447                                arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0 ) {
     448                                ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
     449                                ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( otherArray->get_dimension() );
     450                                assert(ce1 && ce2);
     451
     452                                Constant * c1 = ce1->get_constant();
     453                                Constant * c2 = ce2->get_constant();
     454
     455                                if ( c1->get_value() != c2->get_value() ) {
     456                                        // does not unify if the dimension is different
     457                                        return;
     458                                }
     459                        }
     460
    431461                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    432462                } // if
     
    436466        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    437467                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     468                        // Type * commonType;
     469                        // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    438470                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    439471                                return false;
     
    450482                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    451483                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    452  
     484
    453485                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    454486       
     
    476508                handleRefType( inst, other );
    477509                if ( ! result ) return;
    478                 // Check that parameters of type unify, if any
     510                // Check that parameters of types unify, if any
    479511                std::list< Expression* > params = inst->get_parameters();
    480                 if ( ! params.empty() ) {
    481                         std::list< TypeDecl* > *baseParams = inst->get_baseParameters();
    482                         if ( ! baseParams ) {
     512                std::list< Expression* > otherParams = ((RefType*)other)->get_parameters();
     513
     514                std::list< Expression* >::const_iterator it = params.begin(), jt = otherParams.begin();
     515                for ( ; it != params.end() && jt != otherParams.end(); ++it, ++jt ) {
     516                        TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
     517                        assert(param && "Aggregate parameters should be type expressions");
     518                        TypeExpr *otherParam = dynamic_cast< TypeExpr* >(*jt);
     519                        assert(otherParam && "Aggregate parameters should be type expressions");
     520
     521                        if ( ! unifyExact( param->get_type(), otherParam->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode(false, false), indexer ) ) {
    483522                                result = false;
    484523                                return;
    485524                        }
    486                         std::list< Expression* >::const_iterator it = params.begin();
    487                         std::list< TypeDecl* >::const_iterator baseIt = baseParams->begin();
    488                         while ( it != params.end() && baseIt != baseParams->end()) {
    489                                 TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    490                                 assert(param && "Aggregate parameters should be type expressions");
    491                                 TypeInstType baseType(Type::Qualifiers(), (*baseIt)->get_name(), *baseIt);
    492                                 if ( ! unifyExact( param->get_type(), &baseType, env, needAssertions, haveAssertions, openVars, WidenMode(false, false), indexer ) ) {
    493                                         result = false;
    494                                         return;
    495                                 }
    496                                
    497                                 ++it;
    498                                 ++baseIt;
    499                         }
    500                         if ( it != params.end() || baseIt != baseParams->end() ) {
    501                                 result = false;
    502                         }
    503525                }
     526                result = ( it == params.end() && jt == otherParams.end() );
    504527        }
    505528
Note: See TracChangeset for help on using the changeset viewer.