Changeset 65197c2 for src/ResolvExpr
- Timestamp:
- Dec 5, 2017, 2:17:17 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 971d9f2, a85e44c, c13e8dc8
- Parents:
- 12d2dc8 (diff), 866f560 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/ResolvExpr
- Files:
-
- 4 edited
-
AlternativeFinder.cc (modified) (12 diffs)
-
AlternativeFinder.h (modified) (4 diffs)
-
Resolver.cc (modified) (5 diffs)
-
typeops.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r12d2dc8 r65197c2 83 83 } 84 84 85 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 86 Indenter indent = { Indenter::tabsize, indentAmt }; 87 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 88 i->print( os, indent ); 89 os << std::endl; 90 } 91 } 92 85 93 namespace { 86 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {87 Indenter indent = { Indenter::tabsize, indentAmt };88 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {89 i->print( os, indent );90 os << std::endl;91 }92 }93 94 94 void makeExprList( const AltList &in, std::list< Expression* > &out ) { 95 95 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) { … … 469 469 std::cerr << std::endl; 470 470 ) 471 std::list< DeclarationWithType*> candidates;471 std::list< SymTab::Indexer::IdData > candidates; 472 472 decls.lookupId( curDecl->get_name(), candidates ); 473 473 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 474 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 474 for ( const auto & data : candidates ) { 475 DeclarationWithType * candidate = data.id; 475 476 PRINT( 476 477 std::cerr << "inferRecursive: candidate is "; 477 (*candidate)->print( std::cerr );478 candidate->print( std::cerr ); 478 479 std::cerr << std::endl; 479 480 ) … … 482 483 TypeEnvironment newEnv( newAlt.env ); 483 484 OpenVarSet newOpenVars( openVars ); 484 Type *adjType = (*candidate)->get_type()->clone();485 Type *adjType = candidate->get_type()->clone(); 485 486 adjustExprType( adjType, newEnv, indexer ); 486 487 adjType->accept( global_renamer ); … … 500 501 Alternative newerAlt( newAlt ); 501 502 newerAlt.env = newEnv; 502 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() ); 503 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 503 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 504 504 505 505 // everything with an empty idChain was pulled in by the current assertion. … … 516 516 // DOESN'T WORK: grandchild nodes conflict with their cousins 517 517 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 518 Expression *varExpr = new VariableExpr( candDecl);518 Expression *varExpr = data.combine(); 519 519 delete varExpr->get_result(); 520 520 varExpr->set_result( adjType->clone() ); … … 522 522 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 523 523 curDecl->print( std::cerr ); 524 std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";525 (*candidate)->print( std::cerr );524 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 525 candidate->print( std::cerr ); 526 526 std::cerr << std::endl; 527 527 ) … … 532 532 } 533 533 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 535 535 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 536 536 } else { … … 1317 1317 1318 1318 void AlternativeFinder::visit( NameExpr *nameExpr ) { 1319 std::list< DeclarationWithType*> declList;1319 std::list< SymTab::Indexer::IdData > declList; 1320 1320 indexer.lookupId( nameExpr->get_name(), declList ); 1321 1321 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 1322 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 1323 VariableExpr newExpr( *i ); 1324 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1322 for ( auto & data : declList ) { 1323 Expression * newExpr = data.combine(); 1324 // xxx - add in extra cost for with-statement exprs? 1325 alternatives.push_back( Alternative( newExpr, env, Cost::zero ) ); 1325 1326 PRINT( 1326 1327 std::cerr << "decl is "; 1327 (*i)->print( std::cerr );1328 data.id->print( std::cerr ); 1328 1329 std::cerr << std::endl; 1329 1330 std::cerr << "newExpr is "; 1330 newExpr .print( std::cerr );1331 newExpr->print( std::cerr ); 1331 1332 std::cerr << std::endl; 1332 1333 ) … … 1420 1421 } 1421 1422 1422 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 1423 // assume no polymorphism 1424 // assume no implicit conversions 1425 assert( function->get_parameters().size() == 1 ); 1426 PRINT( 1427 std::cerr << "resolvAttr: funcDecl is "; 1428 funcDecl->print( std::cerr ); 1429 std::cerr << " argType is "; 1430 argType->print( std::cerr ); 1431 std::cerr << std::endl; 1432 ) 1433 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1434 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 1435 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 1436 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 1437 } // for 1438 } // if 1423 namespace { 1424 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1425 // assume no polymorphism 1426 // assume no implicit conversions 1427 assert( function->get_parameters().size() == 1 ); 1428 PRINT( 1429 std::cerr << "resolvAttr: funcDecl is "; 1430 data.id->print( std::cerr ); 1431 std::cerr << " argType is "; 1432 argType->print( std::cerr ); 1433 std::cerr << std::endl; 1434 ) 1435 const SymTab::Indexer & indexer = finder.get_indexer(); 1436 AltList & alternatives = finder.get_alternatives(); 1437 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1438 alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) ); 1439 for ( DeclarationWithType * retVal : function->returnVals ) { 1440 alternatives.back().expr->result = retVal->get_type()->clone(); 1441 } // for 1442 } // if 1443 } 1439 1444 } 1440 1445 … … 1443 1448 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1444 1449 assert( nameExpr ); 1445 std::list< DeclarationWithType*> attrList;1450 std::list< SymTab::Indexer::IdData > attrList; 1446 1451 indexer.lookupId( nameExpr->get_name(), attrList ); 1447 1452 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1448 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1453 for ( auto & data : attrList ) { 1454 DeclarationWithType * id = data.id; 1449 1455 // check if the type is function 1450 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {1456 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1451 1457 // assume exactly one parameter 1452 1458 if ( function->get_parameters().size() == 1 ) { 1453 1459 if ( attrExpr->get_isType() ) { 1454 resolveAttr( *i, function, attrExpr->get_type(), env);1460 resolveAttr( data, function, attrExpr->get_type(), env, *this ); 1455 1461 } else { 1456 1462 AlternativeFinder finder( indexer, env ); … … 1458 1464 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1459 1465 if ( choice->expr->get_result()->size() == 1 ) { 1460 resolveAttr( *i, function, choice->expr->get_result(), choice->env);1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this ); 1461 1467 } // fi 1462 1468 } // for … … 1466 1472 } // for 1467 1473 } else { 1468 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1469 VariableExpr newExpr( *i ); 1470 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1474 for ( auto & data : attrList ) { 1475 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) ); 1471 1476 renameTypes( alternatives.back().expr ); 1472 1477 } // for -
src/ResolvExpr/AlternativeFinder.h
r12d2dc8 r65197c2 142 142 template< typename OutputIterator > 143 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );145 144 146 145 const SymTab::Indexer &indexer; … … 151 150 152 151 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 153 void referenceToRvalueConversion( Expression *& expr );154 152 155 153 template< typename InputIterator, typename OutputIterator > … … 174 172 175 173 Cost sumCost( const AltList &in ); 174 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ); 176 175 177 176 template< typename InputIterator > … … 181 180 } 182 181 } 182 183 183 } // namespace ResolvExpr 184 184 -
src/ResolvExpr/Resolver.cc
r12d2dc8 r65197c2 26 26 #include "Common/utility.h" // for ValueGuard, group_iterate 27 27 #include "CurrentObject.h" // for CurrentObject 28 #include "InitTweak/GenInit.h" 28 29 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 29 30 #include "RenameVars.h" // for RenameVars, global_renamer … … 40 41 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 41 42 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h" 42 44 #include "typeops.h" // for extractResultType 43 45 #include "Unify.h" // for unify … … 46 48 47 49 namespace ResolvExpr { 48 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd { 49 51 Resolver() {} 50 52 Resolver( const SymTab::Indexer & other ) { … … 74 76 void previsit( CatchStmt *catchStmt ); 75 77 void previsit( WaitForStmt * stmt ); 78 void previsit( WithStmt * withStmt ); 76 79 77 80 void previsit( SingleInit *singleInit ); … … 571 574 } 572 575 576 bool isStructOrUnion( Type * t ) { 577 t = t->stripReferences(); 578 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ); 579 } 580 581 void Resolver::previsit( WithStmt * withStmt ) { 582 for ( Expression *& expr : withStmt->exprs ) { 583 TypeEnvironment env; 584 AlternativeFinder finder( indexer, env ); 585 finder.findWithAdjustment( expr ); 586 587 // only struct- and union-typed expressions are viable candidates 588 AltList candidates; 589 for ( Alternative & alt : finder.get_alternatives() ) { 590 if ( isStructOrUnion( alt.expr->result ) ) { 591 candidates.push_back( std::move( alt ) ); 592 } 593 } 594 595 // choose the lowest cost expression among the candidates 596 AltList winners; 597 findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) ); 598 if ( winners.size() == 0 ) { 599 throw SemanticError( "No reasonable alternatives for with statement expression: ", expr ); 600 } else if ( winners.size() != 1 ) { 601 std::ostringstream stream; 602 stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n"; 603 expr->print( stream ); 604 stream << "Alternatives are:\n"; 605 printAlts( winners, stream, 1 ); 606 throw SemanticError( stream.str() ); 607 } 608 609 // there is one unambiguous interpretation - move the expression into the with statement 610 Alternative & alt = winners.front(); 611 finishExpr( alt.expr, alt.env, expr->env ); 612 delete expr; 613 expr = alt.expr; 614 alt.expr = nullptr; 615 616 // if with expression might be impure, create a temporary so that it is evaluated once 617 if ( Tuples::maybeImpure( expr ) ) { 618 static UniqueName tmpNamer( "_with_tmp_" ); 619 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) ); 620 expr = new VariableExpr( tmp ); 621 stmtsToAddBefore.push_back( new DeclStmt( tmp ) ); 622 if ( InitTweak::isConstructable( tmp->type ) ) { 623 // generate ctor/dtor and resolve them 624 tmp->init = InitTweak::genCtorInit( tmp ); 625 tmp->accept( *visitor ); 626 } 627 } 628 } 629 } 630 573 631 template< typename T > 574 632 bool isCharType( T t ) { -
src/ResolvExpr/typeops.h
r12d2dc8 r65197c2 102 102 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 103 103 104 // in AlternativeFinder.cc 105 void referenceToRvalueConversion( Expression *& expr ); 106 104 107 // flatten tuple type into list of types 105 108 template< typename OutputIterator >
Note:
See TracChangeset
for help on using the changeset viewer.