- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rb1bead1 ra5f0529 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:52:08 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 17 09:14:17201713 // Update Count : 3 011 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 26 11:33:00 2017 13 // Update Count : 31 14 14 // 15 15 … … 67 67 68 68 Cost sumCost( const AltList &in ) { 69 Cost total = Cost::zero;69 Cost total; 70 70 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { 71 71 total += i->cost; … … 144 144 expr->get_result()->accept( global_renamer ); 145 145 } 146 147 void referenceToRvalueConversion( Expression *& expr ) { 148 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) { 149 // cast away reference from expr 150 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() ); 151 } 152 } 153 } // namespace 146 } 154 147 155 148 template< typename InputIterator, typename OutputIterator > … … 220 213 void AlternativeFinder::addAnonConversions( const Alternative & alt ) { 221 214 // adds anonymous member interpretations whenever an aggregate value type is seen. 222 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value 223 std::unique_ptr<Expression> aggrExpr( alt.expr->clone() ); 224 alt.env.apply( aggrExpr->get_result() ); 225 Type * aggrType = aggrExpr->get_result(); 226 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 227 aggrType = aggrType->stripReferences(); 228 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) ); 229 } 230 231 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 215 Expression * expr = alt.expr->clone(); 216 std::unique_ptr< Expression > manager( expr ); // RAII for expr 217 alt.env.apply( expr->get_result() ); 218 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) { 232 219 NameExpr nameExpr( "" ); 233 addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );234 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {220 addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr ); 221 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) { 235 222 NameExpr nameExpr( "" ); 236 addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );223 addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr ); 237 224 } // if 238 225 } … … 290 277 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 291 278 292 Cost convCost = Cost::zero;279 Cost convCost( 0, 0, 0 ); 293 280 std::list< DeclarationWithType* >& formals = function->get_parameters(); 294 281 std::list< DeclarationWithType* >::iterator formal = formals.begin(); … … 303 290 actualType->print( std::cerr, 8 ); 304 291 ) 305 Cost actualCost = Cost::zero;292 Cost actualCost; 306 293 if ( formal == formals.end() ) { 307 294 if ( function->get_isVarArgs() ) { 308 convCost.incUnsafe(); 309 // convert reference-typed expressions to value-typed expressions 310 referenceToRvalueConversion( *actualExpr ); 295 convCost += Cost( 1, 0, 0 ); 311 296 continue; 312 297 } else { … … 320 305 std::cerr << std::endl << " to "; 321 306 formalType->print( std::cerr, 8 ); 322 std::cerr << std::endl << "environment is: ";323 alt.env.print( std::cerr, 8 );324 std::cerr << std::endl;325 307 ) 326 308 Cost newCost = conversionCost( actualType, formalType, indexer, alt.env ); … … 334 316 convCost += newCost; 335 317 actualCost += newCost; 336 if ( actualCost != Cost ::zero) {318 if ( actualCost != Cost( 0, 0, 0 ) ) { 337 319 Type *newType = formalType->clone(); 338 320 alt.env.apply( newType ); 339 321 *actualExpr = new CastExpr( *actualExpr, newType ); 340 322 } 341 convCost .incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ));323 convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 ); 342 324 ++formal; // can't be in for-loop update because of the continue 343 325 } … … 361 343 } 362 344 convCost += newCost; 363 convCost .incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ));345 convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 ); 364 346 } 365 347 … … 418 400 Expression * actual = actualIt->expr; 419 401 Type * actualType = actual->get_result(); 420 421 402 PRINT( 422 403 std::cerr << "formal type is "; … … 427 408 ) 428 409 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 429 // std::cerr << "unify failed" << std::endl;430 410 return false; 431 411 } … … 472 452 // match flattened actuals with formal parameters - actuals will be grouped to match 473 453 // with formals as appropriate 474 Cost cost = Cost::zero;454 Cost cost; 475 455 std::list< Expression * > newExprs; 476 456 ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal ); … … 663 643 makeExprList( instantiatedActuals, appExpr->get_args() ); 664 644 PRINT( 665 std::cerr << "instantiate function success: " << appExpr << std::endl;666 645 std::cerr << "need assertions:" << std::endl; 667 646 printAssertionSet( resultNeed, std::cerr, 8 ); … … 684 663 UntypedExpr *vexpr = untypedExpr->clone(); 685 664 vexpr->set_result( pt.clone() ); 686 alternatives.push_back( Alternative( vexpr, env, Cost ::zero) );665 alternatives.push_back( Alternative( vexpr, env, Cost()) ); 687 666 return; 688 667 } … … 702 681 AltList candidates; 703 682 SemanticError errors; 704 for ( AltList:: iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {683 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) { 705 684 try { 706 685 PRINT( … … 709 688 ) 710 689 // check if the type is pointer to function 711 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 690 PointerType *pointer; 691 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) { 712 692 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 713 referenceToRvalueConversion( func->expr );714 693 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 715 694 // XXX … … 717 696 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 718 697 } 719 } 720 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 721 referenceToRvalueConversion( func->expr ); 722 EqvClass eqvClass; 723 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 724 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 725 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 726 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 727 } // for 698 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) { 699 EqvClass eqvClass; 700 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 701 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 702 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 703 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) ); 704 } // for 705 } // if 728 706 } // if 729 707 } // if … … 744 722 } 745 723 746 for ( AltList:: iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {724 for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 747 725 // check if the type is pointer to function 748 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 726 PointerType *pointer; 727 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) { 749 728 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 750 referenceToRvalueConversion( funcOp->expr );751 729 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 752 730 AltList currentAlt; … … 775 753 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 776 754 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() ); 777 std::cerr << "Case +++++++++++++ " << appExpr->get_function()<< std::endl;755 std::cerr << "Case +++++++++++++" << std::endl; 778 756 std::cerr << "formals are:" << std::endl; 779 757 printAll( function->get_parameters(), std::cerr, 8 ); … … 818 796 bool isLvalue( Expression *expr ) { 819 797 // xxx - recurse into tuples? 820 return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ));798 return expr->has_result() && expr->get_result()->get_lvalue(); 821 799 } 822 800 … … 832 810 833 811 Expression * restructureCast( Expression * argExpr, Type * toType ) { 834 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) { 835 // Argument expression is a tuple and the target type is not void and not a reference type. 836 // Cast each member of the tuple to its corresponding target type, producing the tuple of those 837 // cast expressions. If there are more components of the tuple than components in the target type, 838 // then excess components do not come out in the result expression (but UniqueExprs ensure that 839 // side effects will still be done). 812 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) { 813 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 814 // to its corresponding target type, producing the tuple of those cast expressions. If there are 815 // more components of the tuple than components in the target type, then excess components do not 816 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 840 817 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 841 818 // expressions which may contain side effects require a single unique instance of the expression. … … 878 855 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 879 856 // to. 880 int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();857 int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size(); 881 858 if ( discardedValues < 0 ) continue; 882 859 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 883 860 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 884 861 // unification run for side-effects 885 unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );886 Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env );862 unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 863 Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env ); 887 864 if ( thisCost != Cost::infinity ) { 888 865 // count one safe conversion for each value that is thrown away 889 thisCost .incSafe(discardedValues );866 thisCost += Cost( 0, 0, discardedValues ); 890 867 891 868 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); … … 901 878 } 902 879 880 void AlternativeFinder::visit( VirtualCastExpr * castExpr ) { 881 assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." ); 882 AlternativeFinder finder( indexer, env ); 883 // don't prune here, since it's guaranteed all alternatives will have the same type 884 // (giving the alternatives different types is half of the point of ConstructorExpr nodes) 885 finder.findWithAdjustment( castExpr->get_arg(), false ); 886 for ( Alternative & alt : finder.alternatives ) { 887 alternatives.push_back( Alternative( 888 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ), 889 alt.env, alt.cost ) ); 890 } 891 } 892 903 893 void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) { 904 894 AlternativeFinder funcFinder( indexer, env ); 905 895 funcFinder.findWithAdjustment( memberExpr->get_aggregate() ); 906 896 for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) { 907 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value 908 std::unique_ptr<Expression> aggrExpr( agg->expr->clone() ); 909 Type * aggrType = aggrExpr->get_result(); 910 if ( dynamic_cast< ReferenceType * >( aggrType ) ) { 911 aggrType = aggrType->stripReferences(); 912 aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) ); 913 } 914 // find member of the given type 915 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 916 addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 917 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 918 addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 919 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 920 addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() ); 897 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) { 898 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 899 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) { 900 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 901 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) { 902 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() ); 921 903 } // if 922 904 } // for … … 933 915 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 934 916 VariableExpr newExpr( *i, nameExpr->get_argName() ); 935 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ::zero) );917 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) ); 936 918 PRINT( 937 919 std::cerr << "decl is "; … … 1077 1059 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1078 1060 VariableExpr newExpr( *i ); 1079 alternatives.push_back( Alternative( newExpr.clone(), env, Cost ::zero) );1061 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) ); 1080 1062 renameTypes( alternatives.back().expr ); 1081 1063 } // for … … 1250 1232 if ( thisCost != Cost::infinity ) { 1251 1233 // count one safe conversion for each value that is thrown away 1252 thisCost .incSafe(discardedValues );1234 thisCost += Cost( 0, 0, discardedValues ); 1253 1235 candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) ); 1254 1236 }
Note:
See TracChangeset
for help on using the changeset viewer.