Changes in src/ResolvExpr/Unify.cc [721f17a:4040425]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r721f17a r4040425 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 : Fri Jun 26 14:57:05 201513 // Update Count : 712 // Last Modified On : Wed Mar 2 17:37:05 2016 13 // Update Count : 37 14 14 // 15 15 … … 25 25 #include "SynTree/Declaration.h" 26 26 #include "SymTab/Indexer.h" 27 #include " utility.h"28 29 30 // #define DEBUG27 #include "Common/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( ContextInstType *aggregateUseType);58 virtual void visit(TraitInstType *aggregateUseType); 59 59 virtual void visit(TypeInstType *aggregateUseType); 60 60 virtual void visit(TupleType *tupleType); 61 virtual void visit(VarArgsType *varArgsType); 61 62 62 63 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 64 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other ); 63 65 64 66 bool result; … … 73 75 }; 74 76 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) 75 79 bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common ); 76 80 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 77 81 78 82 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 79 83 TypeEnvironment newEnv; 80 OpenVarSet openVars ;84 OpenVarSet openVars, closedVars; // added closedVars 81 85 AssertionSet needAssertions, haveAssertions; 82 86 Type *newFirst = first->clone(), *newSecond = second->clone(); 83 87 env.apply( newFirst ); 84 88 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 85 95 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 86 96 delete newFirst; … … 127 137 case TypeDecl::Dtype: 128 138 return ! isFtype( type, indexer ); 129 139 130 140 case TypeDecl::Ftype: 131 141 return isFtype( type, indexer ); … … 148 158 if ( curClass.type ) { 149 159 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 150 161 std::auto_ptr< Type > newType( curClass.type->clone() ); 151 162 newType->get_qualifiers() = typeInst->get_qualifiers(); … … 185 196 bool widen1 = false, widen2 = false; 186 197 Type *type1 = 0, *type2 = 0; 187 198 188 199 if ( env.lookup( var1->get_name(), class1 ) ) { 189 200 hasClass1 = true; … … 206 217 widen2 = widenMode.widenSecond && class2.allowWidening; 207 218 } // if 208 219 209 220 if ( type1 && type2 ) { 210 221 // std::cout << "has type1 && type2" << std::endl; … … 280 291 TypeEnvironment debugEnv( env ); 281 292 #endif 293 if ( type1->get_qualifiers() != type2->get_qualifiers() ) { 294 return false; 295 } 296 282 297 bool result; 283 298 TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 ); … … 292 307 bool isopen1 = var1 && ( entry1 != openVars.end() ); 293 308 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 ) { 309 310 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 297 311 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 298 312 } else if ( isopen1 ) { … … 419 433 420 434 void Unify::visit(ArrayType *arrayType) { 421 // XXX -- compare array dimension422 435 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 423 438 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 424 463 result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 425 464 } // if … … 429 468 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 430 469 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 ) ) { 431 472 if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 432 473 return false; … … 443 484 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 444 485 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { 445 486 446 487 if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 447 488 448 489 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 449 490 … … 458 499 459 500 template< typename RefType > 460 void Unify::handleRefType( RefType *inst, Type *other ) { 501 void Unify::handleRefType( RefType *inst, Type *other ) { 502 // check that other type is compatible and named the same 461 503 RefType *otherStruct = dynamic_cast< RefType* >( other ); 462 504 result = otherStruct && inst->get_name() == otherStruct->get_name(); 463 } 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 } 464 530 465 531 void Unify::visit(StructInstType *structInst) { 466 handle RefType( structInst, type2 );532 handleGenericRefType( structInst, type2 ); 467 533 } 468 534 469 535 void Unify::visit(UnionInstType *unionInst) { 470 handle RefType( unionInst, type2 );536 handleGenericRefType( unionInst, type2 ); 471 537 } 472 538 … … 475 541 } 476 542 477 void Unify::visit( ContextInstType *contextInst) {543 void Unify::visit(TraitInstType *contextInst) { 478 544 handleRefType( contextInst, type2 ); 479 545 } … … 518 584 } 519 585 586 void Unify::visit(VarArgsType *varArgsType) { 587 result = dynamic_cast< VarArgsType* >( type2 ); 588 } 589 520 590 } // namespace ResolvExpr 521 591
Note:
See TracChangeset
for help on using the changeset viewer.