Changes in src/ResolvExpr/Resolver.cc [0a60c04:36982fc]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r0a60c04 r36982fc 26 26 #include "Common/utility.h" // for ValueGuard, group_iterate 27 27 #include "CurrentObject.h" // for CurrentObject 28 #include "InitTweak/GenInit.h"29 28 #include "InitTweak/InitTweak.h" // for isIntrinsicSingleArgCallStmt 30 29 #include "RenameVars.h" // for RenameVars, global_renamer … … 41 40 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution 42 41 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 43 #include "Tuples/Tuples.h"44 42 #include "typeops.h" // for extractResultType 45 43 #include "Unify.h" // for unify … … 48 46 49 47 namespace ResolvExpr { 50 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting , public WithStmtsToAdd{48 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting { 51 49 Resolver() {} 52 50 Resolver( const SymTab::Indexer & other ) { … … 76 74 void previsit( CatchStmt *catchStmt ); 77 75 void previsit( WaitForStmt * stmt ); 78 void previsit( WithStmt * withStmt );79 76 80 77 void previsit( SingleInit *singleInit ); … … 574 571 } 575 572 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 candidates588 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 candidates596 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 statement610 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 once617 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 them624 tmp->init = InitTweak::genCtorInit( tmp );625 tmp->accept( *visitor );626 }627 }628 }629 }630 631 573 template< typename T > 632 574 bool isCharType( T t ) {
Note:
See TracChangeset
for help on using the changeset viewer.