Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r4040425 r721f17a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Unify.cc --
     7// Unify.cc -- 
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:37:05 2016
    13 // Update Count     : 37
     12// Last Modified On : Fri Jun 26 14:57:05 2015
     13// Update Count     : 7
    1414//
    1515
     
    2525#include "SynTree/Declaration.h"
    2626#include "SymTab/Indexer.h"
    27 #include "Common/utility.h"
    28 
    29 
    30 // #define DEBUG
     27#include "utility.h"
     28
     29
     30//#define DEBUG
    3131
    3232namespace ResolvExpr {
     
    3838                WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
    3939                operator bool() { return widenFirst && widenSecond; }
    40 
     40 
    4141                bool widenFirst : 1, widenSecond : 1;
    4242        };
     
    4545          public:
    4646                Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    47 
     47 
    4848                bool get_result() const { return result; }
    4949          private:
     
    5656                virtual void visit(UnionInstType *aggregateUseType);
    5757                virtual void visit(EnumInstType *aggregateUseType);
    58                 virtual void visit(TraitInstType *aggregateUseType);
     58                virtual void visit(ContextInstType *aggregateUseType);
    5959                virtual void visit(TypeInstType *aggregateUseType);
    6060                virtual void visit(TupleType *tupleType);
    61                 virtual void visit(VarArgsType *varArgsType);
    6261
    6362                template< typename RefType > void handleRefType( RefType *inst, Type *other );
    64                 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    6563
    6664                bool result;
     
    7573        };
    7674
    77         /// Attempts an inexact unification of type1 and type2.
    78         /// Returns false if no such unification; if the types can be unified, sets common (unless they unify exactly and have identical type qualifiers)
    7975        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    8076        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    81 
     77 
    8278        bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    8379                TypeEnvironment newEnv;
    84                 OpenVarSet openVars, closedVars; // added closedVars
     80                OpenVarSet openVars;
    8581                AssertionSet needAssertions, haveAssertions;
    8682                Type *newFirst = first->clone(), *newSecond = second->clone();
    8783                env.apply( newFirst );
    8884                env.apply( newSecond );
    89 
    90                 // do we need to do this? Seems like we do, types should be able to be compatible if they
    91                 // have free variables that can unify
    92                 findOpenVars( newFirst, openVars, closedVars, needAssertions, haveAssertions, false );
    93                 findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
    94 
    9585                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    9686                delete newFirst;
     
    137127                  case TypeDecl::Dtype:
    138128                        return ! isFtype( type, indexer );
    139 
     129 
    140130                  case TypeDecl::Ftype:
    141131                        return isFtype( type, indexer );
     
    158148                        if ( curClass.type ) {
    159149                                Type *common = 0;
    160                                 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    161150                                std::auto_ptr< Type > newType( curClass.type->clone() );
    162151                                newType->get_qualifiers() = typeInst->get_qualifiers();
     
    196185                bool widen1 = false, widen2 = false;
    197186                Type *type1 = 0, *type2 = 0;
    198 
     187 
    199188                if ( env.lookup( var1->get_name(), class1 ) ) {
    200189                        hasClass1 = true;
     
    217206                        widen2 = widenMode.widenSecond && class2.allowWidening;
    218207                } // if
    219 
     208 
    220209                if ( type1 && type2 ) {
    221210//    std::cout << "has type1 && type2" << std::endl;
     
    291280                TypeEnvironment debugEnv( env );
    292281#endif
    293                 if ( type1->get_qualifiers() != type2->get_qualifiers() ) {
    294                         return false;
    295                 }
    296 
    297282                bool result;
    298283                TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
     
    307292                bool isopen1 = var1 && ( entry1 != openVars.end() );
    308293                bool isopen2 = var2 && ( entry2 != openVars.end() );
    309 
    310                 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 ) {
    311297                        result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    312298                } else if ( isopen1 ) {
     
    433419
    434420        void Unify::visit(ArrayType *arrayType) {
     421                // XXX -- compare array dimension
    435422                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    436                 // to unify, array types must both be VLA or both not VLA
    437                 // and must both have a dimension expression or not have a dimension
    438423                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    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                                 // see C11 Reference Manual 6.7.6.2.6
    450                                 // two array types with size specifiers that are integer constant expressions are
    451                                 // compatible if both size specifiers have the same constant value
    452                                 if ( ce1 && ce2 ) {
    453                                         Constant * c1 = ce1->get_constant();
    454                                         Constant * c2 = ce2->get_constant();
    455 
    456                                         if ( c1->get_value() != c2->get_value() ) {
    457                                                 // does not unify if the dimension is different
    458                                                 return;
    459                                         }
    460                                 }
    461                         }
    462 
    463424                        result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    464425                } // if
     
    468429        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    469430                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    470                         // Type * commonType;
    471                         // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    472431                        if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    473432                                return false;
     
    484443                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    485444                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    486 
     445 
    487446                        if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    488 
     447       
    489448                                if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    490449
     
    499458
    500459        template< typename RefType >
    501         void Unify::handleRefType( RefType *inst, Type *other ) {
    502                 // check that other type is compatible and named the same
     460        void Unify::handleRefType( RefType *inst, Type *other ) { 
    503461                RefType *otherStruct = dynamic_cast< RefType* >( other );
    504462                result = otherStruct && inst->get_name() == otherStruct->get_name();
    505         }
    506 
    507         template< typename RefType >
    508         void Unify::handleGenericRefType( RefType *inst, Type *other ) {
    509                 // Check that other type is compatible and named the same
    510                 handleRefType( inst, other );
    511                 if ( ! result ) return;
    512                 // Check that parameters of types unify, if any
    513                 std::list< Expression* > params = inst->get_parameters();
    514                 std::list< Expression* > otherParams = ((RefType*)other)->get_parameters();
    515 
    516                 std::list< Expression* >::const_iterator it = params.begin(), jt = otherParams.begin();
    517                 for ( ; it != params.end() && jt != otherParams.end(); ++it, ++jt ) {
    518                         TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    519                         assert(param && "Aggregate parameters should be type expressions");
    520                         TypeExpr *otherParam = dynamic_cast< TypeExpr* >(*jt);
    521                         assert(otherParam && "Aggregate parameters should be type expressions");
    522 
    523                         if ( ! unifyExact( param->get_type(), otherParam->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode(false, false), indexer ) ) {
    524                                 result = false;
    525                                 return;
    526                         }
    527                 }
    528                 result = ( it == params.end() && jt == otherParams.end() );
    529         }
     463        } 
    530464
    531465        void Unify::visit(StructInstType *structInst) {
    532                 handleGenericRefType( structInst, type2 );
     466                handleRefType( structInst, type2 );
    533467        }
    534468
    535469        void Unify::visit(UnionInstType *unionInst) {
    536                 handleGenericRefType( unionInst, type2 );
     470                handleRefType( unionInst, type2 );
    537471        }
    538472
     
    541475        }
    542476
    543         void Unify::visit(TraitInstType *contextInst) {
     477        void Unify::visit(ContextInstType *contextInst) {
    544478                handleRefType( contextInst, type2 );
    545479        }
     
    584518        }
    585519
    586         void Unify::visit(VarArgsType *varArgsType) {
    587                 result = dynamic_cast< VarArgsType* >( type2 );
    588         }
    589 
    590520} // namespace ResolvExpr
    591521
Note: See TracChangeset for help on using the changeset viewer.