- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r6f096d2 rc1ed2ee 336 336 } 337 337 338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {338 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 339 339 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {340 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 341 341 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 342 342 } // if … … 344 344 345 345 template< typename StructOrUnionType > 346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 347 347 std::list< Declaration* > members; 348 348 aggInst->lookup( name, members ); 349 349 350 350 for ( Declaration * decl : members ) { 351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {351 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 352 352 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 353 353 // can't construct in place and use vector::back … … 362 362 } 363 363 364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression *member ) {364 void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ) { 365 365 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 366 366 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 368 368 std::string tmp; 369 369 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 370 alternatives.push_back( Alternative{ 370 alternatives.push_back( Alternative{ 371 371 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 372 372 } // if … … 374 374 } 375 375 376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {376 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 377 377 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 378 378 } … … 475 475 } 476 476 477 // specialization cost of return types can't be accounted for directly, it disables 477 // specialization cost of return types can't be accounted for directly, it disables 478 478 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 479 479 // … … 1226 1226 // count one safe conversion for each value that is thrown away 1227 1227 thisCost.incSafe( discardedValues ); 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1230 1230 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1231 1231 inferParameters( newAlt, back_inserter( candidates ) ); … … 1328 1328 if ( sizeofExpr->get_isType() ) { 1329 1329 Type * newType = sizeofExpr->get_type()->clone(); 1330 alternatives.push_back( Alternative{ 1330 alternatives.push_back( Alternative{ 1331 1331 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1332 1332 } else { … … 1343 1343 Alternative &choice = winners.front(); 1344 1344 referenceToRvalueConversion( choice.expr, choice.cost ); 1345 alternatives.push_back( Alternative{ 1345 alternatives.push_back( Alternative{ 1346 1346 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1347 1347 } // if … … 1351 1351 if ( alignofExpr->get_isType() ) { 1352 1352 Type * newType = alignofExpr->get_type()->clone(); 1353 alternatives.push_back( Alternative{ 1353 alternatives.push_back( Alternative{ 1354 1354 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1355 1355 } else { … … 1366 1366 Alternative &choice = winners.front(); 1367 1367 referenceToRvalueConversion( choice.expr, choice.cost ); 1368 alternatives.push_back( Alternative{ 1368 alternatives.push_back( Alternative{ 1369 1369 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1370 1370 } // if … … 1377 1377 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1378 1378 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1379 alternatives.push_back( Alternative{ 1379 alternatives.push_back( Alternative{ 1380 1380 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1381 1381 renameTypes( alternatives.back().expr ); … … 1405 1405 1406 1406 namespace { 1407 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {1407 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1408 1408 // assume no polymorphism 1409 1409 // assume no implicit conversions 1410 assert( function-> parameters.size() == 1 );1410 assert( function->get_parameters().size() == 1 ); 1411 1411 PRINT( 1412 1412 std::cerr << "resolvAttr: funcDecl is "; … … 1418 1418 const SymTab::Indexer & indexer = finder.get_indexer(); 1419 1419 AltList & alternatives = finder.get_alternatives(); 1420 if ( typesCompatibleIgnoreQualifiers( argType, function-> parameters.front()->get_type(), indexer, env ) ) {1420 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1421 1421 Cost cost = Cost::zero; 1422 1422 Expression * newExpr = data.combine( cost ); 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1425 1425 AssertionList{}, Cost::zero, cost } ); 1426 1426 for ( DeclarationWithType * retVal : function->returnVals ) { … … 1431 1431 } 1432 1432 1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {1433 void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) { 1434 1434 // assume no 'pointer-to-attribute' 1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );1435 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1436 1436 assert( nameExpr ); 1437 1437 std::list< SymTab::Indexer::IdData > attrList; … … 1439 1439 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1440 1440 for ( auto & data : attrList ) { 1441 constDeclarationWithType * id = data.id;1441 DeclarationWithType * id = data.id; 1442 1442 // check if the type is function 1443 if ( const FunctionType * function = dynamic_cast< const FunctionType* >( id->get_type() ) ) {1443 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1444 1444 // assume exactly one parameter 1445 if ( function-> parameters.size() == 1 ) {1445 if ( function->get_parameters().size() == 1 ) { 1446 1446 if ( attrExpr->get_isType() ) { 1447 1447 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); … … 1462 1462 Cost cost = Cost::zero; 1463 1463 Expression * newExpr = data.combine( cost ); 1464 alternatives.push_back( Alternative{ 1464 alternatives.push_back( Alternative{ 1465 1465 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1466 1466 renameTypes( alternatives.back().expr ); … … 1469 1469 } 1470 1470 1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {1471 void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) { 1472 1472 AlternativeFinder firstFinder( indexer, env ); 1473 1473 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1486 1486 cloneAll( second.need, need ); 1487 1487 1488 LogicalExpr *newExpr = new LogicalExpr{ 1488 LogicalExpr *newExpr = new LogicalExpr{ 1489 1489 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1492 1492 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1493 1493 } … … 1522 1522 cloneAll( third.need, need ); 1523 1523 AssertionSet have; 1524 1524 1525 1525 // unify true and false types, then infer parameters to produce new alternatives 1526 1526 Type* commonType = nullptr; 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1528 1528 need, have, openVars, indexer, commonType ) ) { 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1530 1530 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1531 1531 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1532 1532 // convert both options to the conditional result type 1533 1533 Cost cost = first.cost + second.cost + third.cost; 1534 cost += computeExpressionConversionCost( 1534 cost += computeExpressionConversionCost( 1535 1535 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1536 cost += computeExpressionConversionCost( 1536 cost += computeExpressionConversionCost( 1537 1537 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1538 1538 // output alternative 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1541 1541 AssertionList( need.begin(), need.end() ), cost }; 1542 1542 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1553 1553 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1554 1554 for ( const Alternative & alt : secondFinder.alternatives ) { 1555 alternatives.push_back( Alternative{ 1555 alternatives.push_back( Alternative{ 1556 1556 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1557 1557 } // for … … 1579 1579 1580 1580 Type* commonType = nullptr; 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1582 1582 openVars, indexer, commonType ) ) { 1583 RangeExpr * newExpr = 1583 RangeExpr * newExpr = 1584 1584 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1585 1585 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1588 1588 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1589 1589 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1612 1612 cloneAll( alt.need, need ); 1613 1613 } 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1617 1617 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1618 1618 } // for … … 1633 1633 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1634 1634 for ( Alternative & alt : finder.alternatives ) { 1635 alternatives.push_back( Alternative{ 1635 alternatives.push_back( Alternative{ 1636 1636 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1637 1637 } … … 1685 1685 cloneAll( alt.need, need ); 1686 1686 AssertionSet have; 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1689 1689 // those are open vars? 1690 1690 PRINT( 1691 1691 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1692 1692 ) 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1697 1697 // types to cast to. 1698 1698 int discardedValues = alt.expr->result->size() - toType->size(); 1699 1699 if ( discardedValues < 0 ) continue; 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1702 1702 // atomic type (e.g. (int)([1, 2, 3])) 1703 1703 1704 1704 // unification run for side-effects 1705 1705 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); … … 1710 1710 // count one safe conversion for each value that is thrown away 1711 1711 thisCost.incSafe( discardedValues ); 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1716 1716 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1717 1717 inferParameters( newAlt, back_inserter( candidates ) );
Note:
See TracChangeset
for help on using the changeset viewer.