Changeset 65197c2 for src/ResolvExpr


Ignore:
Timestamp:
Dec 5, 2017, 2:17:17 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r12d2dc8 r65197c2  
    8383        }
    8484
     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
    8593        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 
    9494                void makeExprList( const AltList &in, std::list< Expression* > &out ) {
    9595                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     
    469469                        std::cerr << std::endl;
    470470                )
    471                 std::list< DeclarationWithType* > candidates;
     471                std::list< SymTab::Indexer::IdData > candidates;
    472472                decls.lookupId( curDecl->get_name(), candidates );
    473473///   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;
    475476                        PRINT(
    476477                                std::cerr << "inferRecursive: candidate is ";
    477                                 (*candidate)->print( std::cerr );
     478                                candidate->print( std::cerr );
    478479                                std::cerr << std::endl;
    479480                        )
     
    482483                        TypeEnvironment newEnv( newAlt.env );
    483484                        OpenVarSet newOpenVars( openVars );
    484                         Type *adjType = (*candidate)->get_type()->clone();
     485                        Type *adjType = candidate->get_type()->clone();
    485486                        adjustExprType( adjType, newEnv, indexer );
    486487                        adjType->accept( global_renamer );
     
    500501                                Alternative newerAlt( newAlt );
    501502                                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() );
    504504
    505505                                // everything with an empty idChain was pulled in by the current assertion.
     
    516516                                // DOESN'T WORK: grandchild nodes conflict with their cousins
    517517                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    518                                 Expression *varExpr = new VariableExpr( candDecl );
     518                                Expression *varExpr = data.combine();
    519519                                delete varExpr->get_result();
    520520                                varExpr->set_result( adjType->clone() );
     
    522522                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    523523                                        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 );
    526526                                        std::cerr << std::endl;
    527527                                )
     
    532532                                }
    533533                                // 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 );
    535535                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    536536                        } else {
     
    13171317
    13181318        void AlternativeFinder::visit( NameExpr *nameExpr ) {
    1319                 std::list< DeclarationWithType* > declList;
     1319                std::list< SymTab::Indexer::IdData > declList;
    13201320                indexer.lookupId( nameExpr->get_name(), declList );
    13211321                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 ) );
    13251326                        PRINT(
    13261327                                std::cerr << "decl is ";
    1327                                 (*i)->print( std::cerr );
     1328                                data.id->print( std::cerr );
    13281329                                std::cerr << std::endl;
    13291330                                std::cerr << "newExpr is ";
    1330                                 newExpr.print( std::cerr );
     1331                                newExpr->print( std::cerr );
    13311332                                std::cerr << std::endl;
    13321333                        )
     
    14201421        }
    14211422
    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                }
    14391444        }
    14401445
     
    14431448                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    14441449                assert( nameExpr );
    1445                 std::list< DeclarationWithType* > attrList;
     1450                std::list< SymTab::Indexer::IdData > attrList;
    14461451                indexer.lookupId( nameExpr->get_name(), attrList );
    14471452                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;
    14491455                                // 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() ) ) {
    14511457                                        // assume exactly one parameter
    14521458                                        if ( function->get_parameters().size() == 1 ) {
    14531459                                                if ( attrExpr->get_isType() ) {
    1454                                                         resolveAttr( *i, function, attrExpr->get_type(), env );
     1460                                                        resolveAttr( data, function, attrExpr->get_type(), env, *this );
    14551461                                                } else {
    14561462                                                        AlternativeFinder finder( indexer, env );
     
    14581464                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    14591465                                                                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 );
    14611467                                                                } // fi
    14621468                                                        } // for
     
    14661472                        } // for
    14671473                } 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 ) );
    14711476                                renameTypes( alternatives.back().expr );
    14721477                        } // for
  • src/ResolvExpr/AlternativeFinder.h

    r12d2dc8 r65197c2  
    142142                template< typename OutputIterator >
    143143                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 );
    145144
    146145                const SymTab::Indexer &indexer;
     
    151150
    152151        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
    153         void referenceToRvalueConversion( Expression *& expr );
    154152
    155153        template< typename InputIterator, typename OutputIterator >
     
    174172
    175173        Cost sumCost( const AltList &in );
     174        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 );
    176175
    177176        template< typename InputIterator >
     
    181180                }
    182181        }
     182
    183183} // namespace ResolvExpr
    184184
  • src/ResolvExpr/Resolver.cc

    r12d2dc8 r65197c2  
    2626#include "Common/utility.h"              // for ValueGuard, group_iterate
    2727#include "CurrentObject.h"               // for CurrentObject
     28#include "InitTweak/GenInit.h"
    2829#include "InitTweak/InitTweak.h"         // for isIntrinsicSingleArgCallStmt
    2930#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    4041#include "SynTree/TypeSubstitution.h"    // for TypeSubstitution
    4142#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
     43#include "Tuples/Tuples.h"
    4244#include "typeops.h"                     // for extractResultType
    4345#include "Unify.h"                       // for unify
     
    4648
    4749namespace 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 {
    4951                Resolver() {}
    5052                Resolver( const SymTab::Indexer & other ) {
     
    7476                void previsit( CatchStmt *catchStmt );
    7577                void previsit( WaitForStmt * stmt );
     78                void previsit( WithStmt * withStmt );
    7679
    7780                void previsit( SingleInit *singleInit );
     
    571574        }
    572575
     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
    573631        template< typename T >
    574632        bool isCharType( T t ) {
  • src/ResolvExpr/typeops.h

    r12d2dc8 r65197c2  
    102102        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
    103103
     104        // in AlternativeFinder.cc
     105        void referenceToRvalueConversion( Expression *& expr );
     106
    104107        // flatten tuple type into list of types
    105108        template< typename OutputIterator >
Note: See TracChangeset for help on using the changeset viewer.