Changes in src/GenPoly/GenPoly.cc [3606fe4:c19edd1]
- File:
-
- 1 edited
-
src/GenPoly/GenPoly.cc (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cc
r3606fe4 rc19edd1 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Sep 14 9:24:00 202213 // Update Count : 1 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 29 21:45:53 2016 13 // Update Count : 14 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 96 85 /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present 97 86 bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) { … … 209 198 } 210 199 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;231 200 } 232 201 … … 409 378 inline D* as( B* p ) { return reinterpret_cast<D*>(p); } 410 379 411 template<typename D, typename B>412 inline D const * as( B const * p ) {413 return reinterpret_cast<D const *>( p );414 }415 416 380 /// Flattens a declaration list 417 381 template<typename Output> … … 427 391 for ( Type* ty : src ) { 428 392 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 );436 393 } 437 394 } … … 452 409 // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue; 453 410 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 voids474 // 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 }479 411 } 480 412 … … 573 505 } 574 506 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 687 507 namespace { 688 508 // temporary hack to avoid re-implementing anything related to TyVarMap
Note:
See TracChangeset
for help on using the changeset viewer.