Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r31f379c r9a063c8  
    4949namespace InitTweak {
    5050        namespace {
    51                 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
    52 
    5351                class InsertImplicitCalls final : public GenPoly::PolyMutator {
    5452                public:
    5553                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    5654                        /// function calls need their parameters to be copy constructed
    57                         static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap );
    58 
    59                         InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
    60                         typedef GenPoly::PolyMutator Parent;
    61                         using Parent::mutate;
     55                        static void insert( std::list< Declaration * > & translationUnit );
     56
     57                        using GenPoly::PolyMutator::mutate;
    6258                        virtual Expression * mutate( ApplicationExpr * appExpr ) override;
    63                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
    64 
    65                         // collects environments for relevant nodes
    66                         EnvMap & envMap;
    6759                };
    6860
     
    7264                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    7365                        /// arguments and return value temporaries
    74                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap );
     66                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
    7567
    7668                        typedef SymTab::Indexer Parent;
    7769                        using Parent::visit;
    7870
    79                         ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {}
    80 
    8171                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    82                         virtual void visit( UniqueExpr * unqExpr ) override;
    83                         virtual void visit( StmtExpr * stmtExpr ) override;
     72                        virtual void visit( UniqueExpr * unqExpr );
    8473
    8574                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    9079                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    9180                        void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    92 
     81                private:
    9382                        TypeSubstitution * env;
    94                         const EnvMap & envMap;
    9583                };
    9684
     
    186174                        static void fixInitializers( std::list< Declaration * > &translationUnit );
    187175
    188                         typedef GenPoly::PolyMutator Parent;
    189                         using Parent::mutate;
     176                        using GenPoly::PolyMutator::mutate;
    190177                        virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override;
    191178
     
    199186                        static void fixCopyCtors( std::list< Declaration * > &translationUnit );
    200187
    201                         typedef GenPoly::PolyMutator Parent;
    202                         using Parent::mutate;
     188                        using GenPoly::PolyMutator::mutate;
    203189                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    204190                        virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    205                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
    206191                };
    207192
     
    263248                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    264249
    265                 EnvMap envMap;
    266 
    267                 InsertImplicitCalls::insert( translationUnit, envMap );
    268                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap );
     250
     251                InsertImplicitCalls::insert( translationUnit );
     252                ResolveCopyCtors::resolveImplicitCalls( translationUnit );
    269253                InsertDtors::insert( translationUnit );
    270254                FixInit::fixInitializers( translationUnit );
     
    285269
    286270        namespace {
    287                 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    288                         InsertImplicitCalls inserter( envMap );
     271                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
     272                        InsertImplicitCalls inserter;
    289273                        mutateAll( translationUnit, inserter );
    290274                }
    291275
    292                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ) {
    293                         ResolveCopyCtors resolver( envMap );
     276                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) {
     277                        ResolveCopyCtors resolver;
    294278                        acceptAll( translationUnit, resolver );
    295279                }
     
    342326
    343327                Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    344                         appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );
     328                        appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
    345329                        assert( appExpr );
    346330
    347331                        if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
    348                                 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
     332                                if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() ) ) {
    349333                                        // optimization: don't need to copy construct in order to call intrinsic functions
    350334                                        return appExpr;
     
    355339                                                Type * t1 = ftype->get_parameters().front()->get_type();
    356340                                                Type * t2 = ftype->get_parameters().back()->get_type();
    357                                                 PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 );
     341                                                PointerType * ptrType = dynamic_cast< PointerType * > ( t1 );
     342                                                assert( ptrType );
    358343
    359344                                                if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
     
    372357                        // wrap each function call so that it is easy to identify nodes that have to be copy constructed
    373358                        ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
    374                         // save the type substitution into the envMap so that it is easy to find.
     359                        // save the type substitution onto the new node so that it is easy to find.
    375360                        // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
    376361                        // The substitution is needed to obtain the type of temporary variables so that copy constructor
     
    381366                        // constructor calls together.
    382367                        assert( env );
    383                         envMap[expr] = env;
     368                        expr->set_env( env );
    384369                        return expr;
    385                 }
    386 
    387                 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {
    388                         assert( env );
    389                         envMap[stmtExpr] = env;
    390                         return Parent::mutate( stmtExpr );
    391370                }
    392371
     
    413392                        assert( resolved );
    414393                        if ( resolved->get_env() ) {
    415                                 // Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes.
    416394                                env->add( *resolved->get_env() );
    417                                 delete resolved->get_env();
    418                                 resolved->set_env( nullptr );
    419395                        } // if
    420396
     
    425401                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    426402                        static UniqueName tempNamer("_tmp_cp");
    427                         assert( env );
    428                         CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; )
     403                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
    429404                        assert( arg->has_result() );
    430405                        Type * result = arg->get_result();
     
    433408                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
    434409                        result = result->clone();
    435                         env->apply( result );
     410                        impCpCtorExpr->get_env()->apply( result );
    436411                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    437412                        tmp->get_type()->set_isConst( false );
     
    462437                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    463438                        Parent::visit( impCpCtorExpr );
    464                         env = envMap.at(impCpCtorExpr);
    465                         assert( env );
     439                        env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
    466440
    467441                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     
    474448                        // each return value from the call needs to be connected with an ObjectDecl at the call site, which is
    475449                        // initialized with the return value and is destructed later
    476                         // xxx - handle named return values?
     450                        // xxx - handle multiple return values
     451                        ApplicationExpr * callExpr = impCpCtorExpr->get_callExpr();
     452                        // xxx - is this right? callExpr may not have the right environment, because it was attached at a higher
     453                        // level. Trying to pass that environment along.
     454                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    477455                        Type * result = appExpr->get_result();
    478456                        if ( ! result->isVoid() ) {
    479457                                static UniqueName retNamer("_tmp_cp_ret");
    480458                                result = result->clone();
    481                                 env->apply( result );
     459                                impCpCtorExpr->get_env()->apply( result );
    482460                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    483461                                ret->get_type()->set_isConst( false );
     
    490468                        } // for
    491469                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
    492                 }
    493 
    494                 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) {
    495                         Parent::visit( stmtExpr );
    496                         env = envMap.at(stmtExpr);
    497                         assert( stmtExpr->get_result() );
    498                         Type * result = stmtExpr->get_result();
    499                         if ( ! result->isVoid() ) {
    500                                 static UniqueName retNamer("_tmp_stmtexpr_ret");
    501 
    502                                 // create variable that will hold the result of the stmt expr
    503                                 result = result->clone();
    504                                 env->apply( result );
    505                                 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    506                                 ret->get_type()->set_isConst( false );
    507                                 stmtExpr->get_returnDecls().push_front( ret );
    508 
    509                                 // must have a non-empty body, otherwise it wouldn't have a result
    510                                 CompoundStmt * body = stmtExpr->get_statements();
    511                                 assert( ! body->get_kids().empty() );
    512                                 // must be an ExprStmt, otherwise it wouldn't have a result
    513                                 ExprStmt * last = safe_dynamic_cast< ExprStmt * >( body->get_kids().back() );
    514                                 last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );
    515 
    516                                 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) );
    517                         } // if
    518 
    519470                }
    520471
     
    541492                }
    542493
     494
    543495                Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    544496                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    545497
    546                         impCpCtorExpr = safe_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
     498                        impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) );
     499                        assert( impCpCtorExpr );
     500
    547501                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    548502                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    604558                                        retExpr = UntypedExpr::createDeref( retExpr );
    605559                                } // if
    606                                 // move env from callExpr to retExpr
    607                                 retExpr->set_env( callExpr->get_env() );
    608                                 callExpr->set_env( nullptr );
     560                                retExpr->set_env( env->clone() );
    609561                                return retExpr;
    610562                        } else {
     
    613565                }
    614566
    615                 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
    616                         stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    617                         assert( stmtExpr->get_result() );
    618                         Type * result = stmtExpr->get_result();
    619                         if ( ! result->isVoid() ) {
    620                                 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    621                                         stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    622                                 } // for
    623                                 // add destructors after current statement
    624                                 for ( Expression * dtor : stmtExpr->get_dtors() ) {
    625                                         stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
    626                                 } // for
    627                                 // must have a non-empty body, otherwise it wouldn't have a result
    628                                 CompoundStmt * body = stmtExpr->get_statements();
    629                                 assert( ! body->get_kids().empty() );
    630                                 assert( ! stmtExpr->get_returnDecls().empty() );
    631                                 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    632                         }
    633                         stmtExpr->get_returnDecls().clear();
    634                         stmtExpr->get_dtors().clear();
    635                         return stmtExpr;
    636                 }
    637 
    638567                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
    639568                        static std::unordered_map< int, UniqueExpr * > unqMap;
    640569                        static std::unordered_set< int > addDeref;
    641570                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
     571                        unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) );
    642572                        if ( unqMap.count( unqExpr->get_id() ) ) {
    643573                                // take data from other UniqueExpr to ensure consistency
     
    652582                                return unqExpr;
    653583                        }
    654                         unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    655584                        unqMap[unqExpr->get_id()] = unqExpr;
    656585                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     
    670599                        // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init
    671600                        // is removed from the ObjectDecl
    672                         objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) );
     601                        objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( objDecl ) );
     602
    673603                        if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    674604                                // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     
    974904                                        // insert and resolve default/copy constructor call for each field that's unhandled
    975905                                        std::list< Statement * > stmt;
    976                                         UntypedExpr * deref = UntypedExpr::createDeref( new VariableExpr( thisParam ) );
     906                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
     907                                        deref->get_args().push_back( new VariableExpr( thisParam ) );
    977908
    978909                                        Expression * arg2 = 0;
Note: See TracChangeset for help on using the changeset viewer.