Changes in src/ResolvExpr/Unify.cc [4040425:721f17a]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r4040425 r721f17a 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Unify.cc -- 7 // Unify.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:37:05 201613 // Update Count : 3712 // Last Modified On : Fri Jun 26 14:57:05 2015 13 // Update Count : 7 14 14 // 15 15 … … 25 25 #include "SynTree/Declaration.h" 26 26 #include "SymTab/Indexer.h" 27 #include " Common/utility.h"28 29 30 // 27 #include "utility.h" 28 29 30 //#define DEBUG 31 31 32 32 namespace ResolvExpr { … … 38 38 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; } 39 39 operator bool() { return widenFirst && widenSecond; } 40 40 41 41 bool widenFirst : 1, widenSecond : 1; 42 42 }; … … 45 45 public: 46 46 Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 47 47 48 48 bool get_result() const { return result; } 49 49 private: … … 56 56 virtual void visit(UnionInstType *aggregateUseType); 57 57 virtual void visit(EnumInstType *aggregateUseType); 58 virtual void visit( TraitInstType *aggregateUseType);58 virtual void visit(ContextInstType *aggregateUseType); 59 59 virtual void visit(TypeInstType *aggregateUseType); 60 60 virtual void visit(TupleType *tupleType); 61 virtual void visit(VarArgsType *varArgsType);62 61 63 62 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 64 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );65 63 66 64 bool result; … … 75 73 }; 76 74 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)79 75 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common ); 80 76 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 81 77 82 78 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 83 79 TypeEnvironment newEnv; 84 OpenVarSet openVars , closedVars; // added closedVars80 OpenVarSet openVars; 85 81 AssertionSet needAssertions, haveAssertions; 86 82 Type *newFirst = first->clone(), *newSecond = second->clone(); 87 83 env.apply( newFirst ); 88 84 env.apply( newSecond ); 89 90 // do we need to do this? Seems like we do, types should be able to be compatible if they91 // have free variables that can unify92 findOpenVars( newFirst, openVars, closedVars, needAssertions, haveAssertions, false );93 findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );94 95 85 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 96 86 delete newFirst; … … 137 127 case TypeDecl::Dtype: 138 128 return ! isFtype( type, indexer ); 139 129 140 130 case TypeDecl::Ftype: 141 131 return isFtype( type, indexer ); … … 158 148 if ( curClass.type ) { 159 149 Type *common = 0; 160 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to161 150 std::auto_ptr< Type > newType( curClass.type->clone() ); 162 151 newType->get_qualifiers() = typeInst->get_qualifiers(); … … 196 185 bool widen1 = false, widen2 = false; 197 186 Type *type1 = 0, *type2 = 0; 198 187 199 188 if ( env.lookup( var1->get_name(), class1 ) ) { 200 189 hasClass1 = true; … … 217 206 widen2 = widenMode.widenSecond && class2.allowWidening; 218 207 } // if 219 208 220 209 if ( type1 && type2 ) { 221 210 // std::cout << "has type1 && type2" << std::endl; … … 291 280 TypeEnvironment debugEnv( env ); 292 281 #endif 293 if ( type1->get_qualifiers() != type2->get_qualifiers() ) {294 return false;295 }296 297 282 bool result; 298 283 TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 ); … … 307 292 bool isopen1 = var1 && ( entry1 != openVars.end() ); 308 293 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 ) { 311 297 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 312 298 } else if ( isopen1 ) { … … 433 419 434 420 void Unify::visit(ArrayType *arrayType) { 421 // XXX -- compare array dimension 435 422 ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 ); 436 // to unify, array types must both be VLA or both not VLA437 // and must both have a dimension expression or not have a dimension438 423 if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) { 439 440 // not positive this is correct in all cases, but it's needed for typedefs441 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.6450 // two array types with size specifiers that are integer constant expressions are451 // compatible if both size specifiers have the same constant value452 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 different458 return;459 }460 }461 }462 463 424 result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 464 425 } // if … … 468 429 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 469 430 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 ) ) {472 431 if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 473 432 return false; … … 484 443 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 485 444 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { 486 445 487 446 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 489 448 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 490 449 … … 499 458 500 459 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 ) { 503 461 RefType *otherStruct = dynamic_cast< RefType* >( other ); 504 462 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 } 530 464 531 465 void Unify::visit(StructInstType *structInst) { 532 handle GenericRefType( structInst, type2 );466 handleRefType( structInst, type2 ); 533 467 } 534 468 535 469 void Unify::visit(UnionInstType *unionInst) { 536 handle GenericRefType( unionInst, type2 );470 handleRefType( unionInst, type2 ); 537 471 } 538 472 … … 541 475 } 542 476 543 void Unify::visit( TraitInstType *contextInst) {477 void Unify::visit(ContextInstType *contextInst) { 544 478 handleRefType( contextInst, type2 ); 545 479 } … … 584 518 } 585 519 586 void Unify::visit(VarArgsType *varArgsType) {587 result = dynamic_cast< VarArgsType* >( type2 );588 }589 590 520 } // namespace ResolvExpr 591 521
Note:
See TracChangeset
for help on using the changeset viewer.