Changeset c8e4d2f8 for src/ResolvExpr/CandidateFinder.cpp
- Timestamp:
- Jun 18, 2019, 11:47:44 AM (4 years ago)
- Branches:
- ADT, arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- a2a85658, b408364
- Parents:
- bc92bee
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CandidateFinder.cpp
rbc92bee rc8e4d2f8 28 28 #include "ExplodedArg.hpp" 29 29 #include "Resolver.h" 30 #include "ResolveTypeof.h" 30 31 #include "SatisfyAssertions.hpp" 31 32 #include "typeops.h" // for adjustExprType, conversionCost, polyCost, specCost … … 38 39 #include "AST/Type.hpp" 39 40 #include "SymTab/Mangler.h" 41 #include "SymTab/Validate.h" // for validateType 40 42 #include "Tuples/Tuples.h" // for handleTupleAssignment 41 43 … … 554 556 } 555 557 558 /// Generate a cast expression from `arg` to `toType` 559 const ast::Expr * restructureCast( const ast::Expr * arg, const ast::Type * toType, bool isGenerated ) { 560 #warning unimplemented 561 (void)arg; (void)toType; (void)isGenerated; 562 assert(false); 563 return nullptr; 564 } 565 556 566 /// Actually visits expressions to find their candidate interpretations 557 567 struct Finder final : public ast::WithShortCircuiting { … … 741 751 /// Adds implicit struct-conversions to the alternative list 742 752 void addAnonConversions( const CandidateRef & cand ) { 743 #warning unimplemented 744 (void)cand; 745 assert(false); 753 // adds anonymous member interpretations whenever an aggregate value type is seen. 754 // it's okay for the aggregate expression to have reference type -- cast it to the 755 // base type to treat the aggregate as the referenced value 756 ast::ptr< ast::Expr > aggrExpr( cand->expr ); 757 ast::ptr< ast::Type > & aggrType = aggrExpr.get_and_mutate()->result; 758 cand->env.apply( aggrType ); 759 760 if ( aggrType.as< ast::ReferenceType >() ) { 761 aggrExpr = 762 new ast::CastExpr{ aggrExpr->location, aggrExpr, aggrType->stripReferences() }; 763 } 764 765 if ( auto structInst = aggrExpr->result.as< ast::StructInstType >() ) { 766 addAggMembers( structInst, aggrExpr, cand, Cost::safe, "" ); 767 } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) { 768 addAggMembers( unionInst, aggrExpr, cand, Cost::safe, "" ); 769 } 770 } 771 772 /// Adds aggregate member interpretations 773 void addAggMembers( 774 const ast::ReferenceToType * aggrInst, const ast::Expr * expr, 775 const CandidateRef & cand, const Cost & addedCost, const std::string & name 776 ) { 777 for ( const ast::Decl * decl : aggrInst->lookup( name ) ) { 778 auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( decl ); 779 CandidateRef newCand = std::make_shared<Candidate>( 780 *cand, new ast::MemberExpr{ expr->location, dwt, expr }, addedCost ); 781 // add anonymous member interpretations whenever an aggregate value type is seen 782 // as a member expression 783 addAnonConversions( newCand ); 784 candidates.emplace_back( move( newCand ) ); 785 } 746 786 } 747 787 … … 915 955 916 956 void postvisit( const ast::CastExpr * castExpr ) { 957 ast::ptr< ast::Type > toType = castExpr->result; 958 assert( toType ); 959 toType = resolveTypeof( toType, symtab ); 960 toType = SymTab::validateType( toType, symtab ); 961 toType = adjustExprType( toType, tenv, symtab ); 962 963 CandidateFinder finder{ symtab, tenv, toType }; 964 finder.find( castExpr->arg, ResolvMode::withAdjustment() ); 965 966 CandidateList matches; 967 for ( CandidateRef & cand : finder.candidates ) { 968 ast::AssertionSet need( cand->need.begin(), cand->need.end() ), have; 969 ast::OpenVarSet open( cand->open ); 970 971 cand->env.extractOpenVars( open ); 972 973 // It is possible that a cast can throw away some values in a multiply-valued 974 // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of the 975 // subexpression results that are cast directly. The candidate is invalid if it 976 // has fewer results than there are types to cast to. 977 int discardedValues = cand->expr->result->size() - toType->size(); 978 if ( discardedValues < 0 ) continue; 979 980 // unification run for side-effects 981 unify( toType, cand->expr->result, cand->env, need, have, open, symtab ); 982 Cost thisCost = castCost( cand->expr->result, toType, symtab, cand->env ); 983 PRINT( 984 std::cerr << "working on cast with result: " << toType << std::endl; 985 std::cerr << "and expr type: " << cand->expr->result << std::endl; 986 std::cerr << "env: " << cand->env << std::endl; 987 ) 988 if ( thisCost != Cost::infinity ) { 989 PRINT( 990 std::cerr << "has finite cost." << std::endl; 991 ) 992 // count one safe conversion for each value that is thrown away 993 thisCost.incSafe( discardedValues ); 994 CandidateRef newCand = std::make_shared<Candidate>( 995 restructureCast( cand->expr, toType, castExpr->isGenerated ), 996 copy( cand->env ), move( open ), move( need ), cand->cost, 997 cand->cost + thisCost ); 998 inferParameters( newCand, matches ); 999 } 1000 } 1001 1002 // castExpr->result should be replaced with toType 1003 // candidates => matches 1004 917 1005 #warning unimplemented 918 1006 (void)castExpr; … … 927 1015 for ( CandidateRef & r : finder.candidates ) { 928 1016 addCandidate( 929 *r, new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } ); 1017 *r, 1018 new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } ); 930 1019 } 931 1020 }
Note: See TracChangeset
for help on using the changeset viewer.