Changeset 23a08aa0 for src/GenPoly/GenPoly.cc
- Timestamp:
- Sep 19, 2022, 8:11:02 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- aa9f215
- Parents:
- ebf8ca5 (diff), ae1d151 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cc
rebf8ca5 r23a08aa0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jun 29 21:45:53 201613 // Update Count : 1 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 14 9:24:00 2022 13 // Update Count : 15 14 14 // 15 15 … … 83 83 } 84 84 85 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 86 for ( ast::ptr<ast::Expr> const & param : params ) { 87 auto paramType = param.as<ast::TypeExpr>(); 88 assertf( paramType, "Aggregate parameters should be type expressions." ); 89 if ( isDynType( paramType->type, tyVars, typeSubs ) ) { 90 return true; 91 } 92 } 93 return false; 94 } 95 85 96 /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present 86 97 bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) { … … 198 209 } 199 210 return 0; 211 } 212 213 const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 214 type = replaceTypeInst( type, typeSubs ); 215 216 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 217 auto var = tyVars.find( inst->name ); 218 if ( var != tyVars.end() && var->second.isComplete ) { 219 return inst; 220 } 221 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { 222 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 223 return inst; 224 } 225 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) { 226 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 227 return inst; 228 } 229 } 230 return nullptr; 200 231 } 201 232 … … 378 409 inline D* as( B* p ) { return reinterpret_cast<D*>(p); } 379 410 411 template<typename D, typename B> 412 inline D const * as( B const * p ) { 413 return reinterpret_cast<D const *>( p ); 414 } 415 380 416 /// Flattens a declaration list 381 417 template<typename Output> … … 391 427 for ( Type* ty : src ) { 392 428 ResolvExpr::flatten( ty, out ); 429 } 430 } 431 432 void flattenList( vector<ast::ptr<ast::Type>> const & src, 433 vector<ast::ptr<ast::Type>> & out ) { 434 for ( auto const & type : src ) { 435 ResolvExpr::flatten( type, out ); 393 436 } 394 437 } … … 409 452 // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue; 410 453 if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false; 454 } 455 456 return true; 457 } 458 459 bool paramListsPolyCompatible( 460 std::vector<ast::ptr<ast::Expr>> const & lparams, 461 std::vector<ast::ptr<ast::Expr>> const & rparams ) { 462 if ( lparams.size() != rparams.size() ) { 463 return false; 464 } 465 466 for ( auto lparam = lparams.begin(), rparam = rparams.begin() ; 467 lparam != lparams.end() ; ++lparam, ++rparam ) { 468 ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>(); 469 assertf( lexpr, "Aggregate parameters should be type expressions" ); 470 ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>(); 471 assertf( rexpr, "Aggregate parameters should be type expressions" ); 472 473 // xxx - might need to let VoidType be a wildcard here too; could have some voids 474 // stuffed in for dtype-statics. 475 // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue; 476 if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) { 477 return false; 478 } 411 479 } 412 480 … … 505 573 } 506 574 575 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) { 576 type_index const lid = typeid(*lhs); 577 578 // Polymorphic types always match: 579 if ( type_index(typeid(ast::TypeInstType)) == lid ) return true; 580 581 type_index const rid = typeid(*rhs); 582 if ( type_index(typeid(ast::TypeInstType)) == rid ) return true; 583 584 // All other types only match if they are the same type: 585 if ( lid != rid ) return false; 586 587 // So remaining types can be examined case by case. 588 // Recurse through type structure (conditions borrowed from Unify.cc). 589 590 if ( type_index(typeid(ast::BasicType)) == lid ) { 591 return as<ast::BasicType>(lhs)->kind == as<ast::BasicType>(rhs)->kind; 592 } else if ( type_index(typeid(ast::PointerType)) == lid ) { 593 ast::PointerType const * l = as<ast::PointerType>(lhs); 594 ast::PointerType const * r = as<ast::PointerType>(rhs); 595 596 // void pointers should match any other pointer type. 597 return is<ast::VoidType>( l->base.get() ) 598 || is<ast::VoidType>( r->base.get() ) 599 || typesPolyCompatible( l->base.get(), r->base.get() ); 600 } else if ( type_index(typeid(ast::ReferenceType)) == lid ) { 601 ast::ReferenceType const * l = as<ast::ReferenceType>(lhs); 602 ast::ReferenceType const * r = as<ast::ReferenceType>(rhs); 603 604 // void references should match any other reference type. 605 return is<ast::VoidType>( l->base.get() ) 606 || is<ast::VoidType>( r->base.get() ) 607 || typesPolyCompatible( l->base.get(), r->base.get() ); 608 } else if ( type_index(typeid(ast::ArrayType)) == lid ) { 609 ast::ArrayType const * l = as<ast::ArrayType>(lhs); 610 ast::ArrayType const * r = as<ast::ArrayType>(rhs); 611 612 if ( l->isVarLen ) { 613 if ( !r->isVarLen ) return false; 614 } else { 615 if ( r->isVarLen ) return false; 616 617 auto lc = l->dimension.as<ast::ConstantExpr>(); 618 auto rc = r->dimension.as<ast::ConstantExpr>(); 619 if ( lc && rc && lc->intValue() != rc->intValue() ) { 620 return false; 621 } 622 } 623 624 return typesPolyCompatible( l->base.get(), r->base.get() ); 625 } else if ( type_index(typeid(ast::FunctionType)) == lid ) { 626 ast::FunctionType const * l = as<ast::FunctionType>(lhs); 627 ast::FunctionType const * r = as<ast::FunctionType>(rhs); 628 629 std::vector<ast::ptr<ast::Type>> lparams, rparams; 630 flattenList( l->params, lparams ); 631 flattenList( r->params, rparams ); 632 if ( lparams.size() != rparams.size() ) return false; 633 for ( unsigned i = 0; i < lparams.size(); ++i ) { 634 if ( !typesPolyCompatible( lparams[i], rparams[i] ) ) return false; 635 } 636 637 std::vector<ast::ptr<ast::Type>> lrets, rrets; 638 flattenList( l->returns, lrets ); 639 flattenList( r->returns, rrets ); 640 if ( lrets.size() != rrets.size() ) return false; 641 for ( unsigned i = 0; i < lrets.size(); ++i ) { 642 if ( !typesPolyCompatible( lrets[i], rrets[i] ) ) return false; 643 } 644 return true; 645 } else if ( type_index(typeid(ast::StructInstType)) == lid ) { 646 ast::StructInstType const * l = as<ast::StructInstType>(lhs); 647 ast::StructInstType const * r = as<ast::StructInstType>(rhs); 648 649 if ( l->name != r->name ) return false; 650 return paramListsPolyCompatible( l->params, r->params ); 651 } else if ( type_index(typeid(ast::UnionInstType)) == lid ) { 652 ast::UnionInstType const * l = as<ast::UnionInstType>(lhs); 653 ast::UnionInstType const * r = as<ast::UnionInstType>(rhs); 654 655 if ( l->name != r->name ) return false; 656 return paramListsPolyCompatible( l->params, r->params ); 657 } else if ( type_index(typeid(ast::EnumInstType)) == lid ) { 658 ast::EnumInstType const * l = as<ast::EnumInstType>(lhs); 659 ast::EnumInstType const * r = as<ast::EnumInstType>(rhs); 660 661 return l->name == r->name; 662 } else if ( type_index(typeid(ast::TraitInstType)) == lid ) { 663 ast::TraitInstType const * l = as<ast::TraitInstType>(lhs); 664 ast::TraitInstType const * r = as<ast::TraitInstType>(rhs); 665 666 return l->name == r->name; 667 } else if ( type_index(typeid(ast::TupleType)) == lid ) { 668 ast::TupleType const * l = as<ast::TupleType>(lhs); 669 ast::TupleType const * r = as<ast::TupleType>(rhs); 670 671 std::vector<ast::ptr<ast::Type>> ltypes, rtypes; 672 flattenList( l->types, ( ltypes ) ); 673 flattenList( r->types, ( rtypes ) ); 674 if ( ltypes.size() != rtypes.size() ) return false; 675 676 for ( unsigned i = 0 ; i < ltypes.size() ; ++i ) { 677 if ( !typesPolyCompatible( ltypes[i], rtypes[i] ) ) return false; 678 } 679 return true; 680 // The remaining types (VoidType, VarArgsType, ZeroType & OneType) 681 // have no variation so will always be equal. 682 } else { 683 return true; 684 } 685 } 686 507 687 namespace { 508 688 // temporary hack to avoid re-implementing anything related to TyVarMap
Note:
See TracChangeset
for help on using the changeset viewer.