- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
ra8706fc r43bd69d 698 698 const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart, 699 699 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 700 if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) {700 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 701 701 // formalType is a TupleType - group actuals into a TupleExpr 702 702 ++nTuples; 703 703 for ( Type* type : *tupleType ) { 704 704 // xxx - dropping initializer changes behaviour from previous, but seems correct 705 // ^^^ need to handle the case where a tuple has a default argument706 705 if ( ! instantiateArgument( 707 706 type, nullptr, args, results, genStart, indexer, nTuples ) ) … … 714 713 } 715 714 return true; 716 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {715 } else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) { 717 716 // formalType is a ttype, consumes all remaining arguments 718 717 // xxx - mixing default arguments with variadic?? … … 917 916 // consider only first exploded actual 918 917 Expression* expr = expl.exprs.front().get(); 919 Type* actualType = expr-> result->clone();918 Type* actualType = expr->get_result()->clone(); 920 919 921 920 PRINT( … … 948 947 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 949 948 // sum cost and accumulate actuals 950 std::list<Expression*>& args = appExpr-> args;949 std::list<Expression*>& args = appExpr->get_args(); 951 950 Cost cost = func.cost; 952 951 const ArgPack* pack = &result; … … 975 974 // add all type variables as open variables now so that those not used in the parameter 976 975 // list are still considered open. 977 funcEnv.add( funcType-> forall);978 979 if ( targetType && ! targetType->isVoid() && ! funcType-> returnVals.empty() ) {976 funcEnv.add( funcType->get_forall() ); 977 978 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 980 979 // attempt to narrow based on expected target type 981 Type * returnType = funcType-> returnVals.front()->get_type();980 Type * returnType = funcType->get_returnVals().front()->get_type(); 982 981 if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars, 983 982 indexer ) ) { … … 992 991 std::size_t genStart = 0; 993 992 994 for ( DeclarationWithType* formal : funcType-> parameters) {993 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 995 994 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 996 995 if ( ! instantiateArgument( 997 obj-> type, obj->init, args, results, genStart, indexer ) )996 obj->get_type(), obj->get_init(), args, results, genStart, indexer ) ) 998 997 return; 999 998 } … … 1076 1075 void AlternativeFinder::Finder::postvisit( UntypedExpr *untypedExpr ) { 1077 1076 AlternativeFinder funcFinder( indexer, env ); 1078 funcFinder.findWithAdjustment( untypedExpr-> function);1077 funcFinder.findWithAdjustment( untypedExpr->get_function() ); 1079 1078 // if there are no function alternatives, then proceeding is a waste of time. 1080 1079 if ( funcFinder.alternatives.empty() ) return; … … 1121 1120 ) 1122 1121 // check if the type is pointer to function 1123 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr-> result->stripReferences() ) ) {1124 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer-> base) ) {1122 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 1123 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 1125 1124 Alternative newFunc( *func ); 1126 1125 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1128 1127 std::back_inserter( candidates ) ); 1129 1128 } 1130 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr-> result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)1129 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 1131 1130 EqvClass eqvClass; 1132 if ( func->env.lookup( typeInst-> name, eqvClass ) && eqvClass.type ) {1131 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 1133 1132 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 1134 1133 Alternative newFunc( *func ); … … 1159 1158 // check if type is a pointer to function 1160 1159 if ( PointerType* pointer = dynamic_cast<PointerType*>( 1161 funcOp->expr-> result->stripReferences() ) ) {1160 funcOp->expr->get_result()->stripReferences() ) ) { 1162 1161 if ( FunctionType* function = 1163 dynamic_cast<FunctionType*>( pointer-> base) ) {1162 dynamic_cast<FunctionType*>( pointer->get_base() ) ) { 1164 1163 Alternative newFunc( *funcOp ); 1165 1164 referenceToRvalueConversion( newFunc.expr, newFunc.cost ); … … 1183 1182 PRINT( 1184 1183 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr ); 1185 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr-> function->result);1186 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer-> base);1187 std::cerr << "Case +++++++++++++ " << appExpr-> function<< std::endl;1184 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 1185 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() ); 1186 std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl; 1188 1187 std::cerr << "formals are:" << std::endl; 1189 printAll( function-> parameters, std::cerr, 8 );1188 printAll( function->get_parameters(), std::cerr, 8 ); 1190 1189 std::cerr << "actuals are:" << std::endl; 1191 printAll( appExpr-> args, std::cerr, 8 );1190 printAll( appExpr->get_args(), std::cerr, 8 ); 1192 1191 std::cerr << "bindings are:" << std::endl; 1193 1192 withFunc.env.print( std::cerr, 8 ); … … 1230 1229 bool isLvalue( Expression *expr ) { 1231 1230 // xxx - recurse into tuples? 1232 return expr->result && ( expr-> result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result) );1231 return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) ); 1233 1232 } 1234 1233 … … 1286 1285 AlternativeFinder finder( indexer, env ); 1287 1286 finder.targetType = toType; 1288 finder.findWithAdjustment( castExpr-> arg);1287 finder.findWithAdjustment( castExpr->get_arg() ); 1289 1288 1290 1289 AltList candidates; … … 1293 1292 OpenVarSet openVars; 1294 1293 1295 alt.env.extractOpenVars( openVars );1296 1297 1294 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1298 1295 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1299 1296 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1300 1297 // to. 1301 int discardedValues = alt.expr-> result->size() - castExpr->result->size();1298 int discardedValues = alt.expr->get_result()->size() - castExpr->get_result()->size(); 1302 1299 if ( discardedValues < 0 ) continue; 1303 1300 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1304 1301 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1305 1302 // unification run for side-effects 1306 unify( castExpr-> result, alt.expr->result, alt.env, needAssertions,1303 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1307 1304 haveAssertions, openVars, indexer ); 1308 Cost thisCost = castCost( alt.expr-> result, castExpr->result, indexer,1305 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1309 1306 alt.env ); 1310 1307 PRINT( … … 1712 1709 AlternativeFinder finder( indexer, env ); 1713 1710 finder.targetType = toType; 1714 finder.findWithAdjustment( initExpr-> expr);1711 finder.findWithAdjustment( initExpr->get_expr() ); 1715 1712 for ( Alternative & alt : finder.get_alternatives() ) { 1716 1713 TypeEnvironment newEnv( alt.env ); … … 1719 1716 PRINT( 1720 1717 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1721 )1718 ) 1722 1719 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1723 1720 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1724 1721 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1725 1722 // to. 1726 int discardedValues = alt.expr-> result->size() - toType->size();1723 int discardedValues = alt.expr->get_result()->size() - toType->size(); 1727 1724 if ( discardedValues < 0 ) continue; 1728 1725 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1729 1726 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1730 1727 // unification run for side-effects 1731 unify( toType, alt.expr-> result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??1732 1733 Cost thisCost = castCost( alt.expr-> result, toType, indexer, newEnv );1728 unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?? 1729 1730 Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv ); 1734 1731 if ( thisCost != Cost::infinity ) { 1735 1732 // count one safe conversion for each value that is thrown away
Note:
See TracChangeset
for help on using the changeset viewer.