Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r02ec390 r1cbca6e  
    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 {
     
    6161
    6262                template< typename RefType > void handleRefType( RefType *inst, Type *other );
    63                 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    6463
    6564                bool result;
     
    8180        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    8281                TypeEnvironment newEnv;
    83                 OpenVarSet openVars;
     82                OpenVarSet openVars, closedVars; // added closedVars
    8483                AssertionSet needAssertions, haveAssertions;
    8584                Type *newFirst = first->clone(), *newSecond = second->clone();
    8685                env.apply( newFirst );
    8786                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
    8893                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    8994                delete newFirst;
     
    426431
    427432        void Unify::visit(ArrayType *arrayType) {
    428                 // XXX -- compare array dimension
    429433                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    430                 if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
     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
    431460                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    432461                } // if
     
    436465        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    437466                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 ) ) {
    438469                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    439470                                return false;
     
    450481                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    451482                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    452  
     483
    453484                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    454485       
     
    465496
    466497        template< typename RefType >
    467         void Unify::handleRefType( RefType *inst, Type *other ) {
    468                 // check that other type is compatible and named the same
     498        void Unify::handleRefType( RefType *inst, Type *other ) { 
    469499                RefType *otherStruct = dynamic_cast< RefType* >( other );
    470500                result = otherStruct && inst->get_name() == otherStruct->get_name();
    471         }
    472 
    473         template< typename RefType >
    474         void Unify::handleGenericRefType( RefType *inst, Type *other ) {
    475                 // Check that other type is compatible and named the same
    476                 handleRefType( inst, other );
    477                 if ( ! result ) return;
    478                 // Check that parameters of type unify, if any
    479                 std::list< Expression* > params = inst->get_parameters();
    480                 if ( ! params.empty() ) {
    481                         std::list< TypeDecl* > *baseParams = inst->get_baseParameters();
    482                         if ( ! baseParams ) {
    483                                 result = false;
    484                                 return;
    485                         }
    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                         }
    503                 }
    504         }
     501        } 
    505502
    506503        void Unify::visit(StructInstType *structInst) {
    507                 handleGenericRefType( structInst, type2 );
     504                handleRefType( structInst, type2 );
    508505        }
    509506
    510507        void Unify::visit(UnionInstType *unionInst) {
    511                 handleGenericRefType( unionInst, type2 );
     508                handleRefType( unionInst, type2 );
    512509        }
    513510
Note: See TracChangeset for help on using the changeset viewer.