Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r1cbca6e r02ec390  
    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 {
     
    6161
    6262                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     63                template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    6364
    6465                bool result;
     
    8081        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    8182                TypeEnvironment newEnv;
    82                 OpenVarSet openVars, closedVars; // added closedVars
     83                OpenVarSet openVars;
    8384                AssertionSet needAssertions, haveAssertions;
    8485                Type *newFirst = first->clone(), *newSecond = second->clone();
    8586                env.apply( newFirst );
    8687                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 
    9388                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    9489                delete newFirst;
     
    431426
    432427        void Unify::visit(ArrayType *arrayType) {
     428                // XXX -- compare array dimension
    433429                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 
     430                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    460431                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    461432                } // if
     
    465436        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    466437                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 ) ) {
    469438                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    470439                                return false;
     
    481450                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    482451                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    483 
     452 
    484453                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    485454       
     
    496465
    497466        template< typename RefType >
    498         void Unify::handleRefType( RefType *inst, Type *other ) { 
     467        void Unify::handleRefType( RefType *inst, Type *other ) {
     468                // check that other type is compatible and named the same
    499469                RefType *otherStruct = dynamic_cast< RefType* >( other );
    500470                result = otherStruct && inst->get_name() == otherStruct->get_name();
    501         } 
     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        }
    502505
    503506        void Unify::visit(StructInstType *structInst) {
    504                 handleRefType( structInst, type2 );
     507                handleGenericRefType( structInst, type2 );
    505508        }
    506509
    507510        void Unify::visit(UnionInstType *unionInst) {
    508                 handleRefType( unionInst, type2 );
     511                handleGenericRefType( unionInst, type2 );
    509512        }
    510513
Note: See TracChangeset for help on using the changeset viewer.