Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r721f17a 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 {
     
    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)
    7577        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    7678        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     
    7880        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    7981                TypeEnvironment newEnv;
    80                 OpenVarSet openVars;
     82                OpenVarSet openVars, closedVars; // added closedVars
    8183                AssertionSet needAssertions, haveAssertions;
    8284                Type *newFirst = first->clone(), *newSecond = second->clone();
    8385                env.apply( newFirst );
    8486                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
    8593                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    8694                delete newFirst;
     
    148156                        if ( curClass.type ) {
    149157                                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
    150159                                std::auto_ptr< Type > newType( curClass.type->clone() );
    151160                                newType->get_qualifiers() = typeInst->get_qualifiers();
     
    280289                TypeEnvironment debugEnv( env );
    281290#endif
     291                if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
     292                        return false;
     293                }
     294
    282295                bool result;
    283296                TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
     
    292305                bool isopen1 = var1 && ( entry1 != openVars.end() );
    293306                bool isopen2 = var2 && ( entry2 != openVars.end() );
    294                 if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
    295                         return false;
    296                 } else if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
     307
     308                if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    297309                        result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    298310                } else if ( isopen1 ) {
     
    419431
    420432        void Unify::visit(ArrayType *arrayType) {
    421                 // XXX -- compare array dimension
    422433                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    423                 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
    424460                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    425461                } // if
     
    429465        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    430466                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 ) ) {
    431469                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    432470                                return false;
     
    443481                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    444482                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    445  
     483
    446484                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    447485       
Note: See TracChangeset for help on using the changeset viewer.