Changeset 31f379c


Ignore:
Timestamp:
Dec 13, 2016, 6:16:21 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
cce9429
Parents:
d5556a3
Message:

add copy constructor code for StmtExpr?, fix usage of environments in FixInit?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rd5556a3 r31f379c  
    4949namespace InitTweak {
    5050        namespace {
     51                typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
     52
    5153                class InsertImplicitCalls final : public GenPoly::PolyMutator {
    5254                public:
    5355                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    5456                        /// function calls need their parameters to be copy constructed
    55                         static void insert( std::list< Declaration * > & translationUnit );
    56 
    57                         using GenPoly::PolyMutator::mutate;
     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;
    5862                        virtual Expression * mutate( ApplicationExpr * appExpr ) override;
     63                        virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     64
     65                        // collects environments for relevant nodes
     66                        EnvMap & envMap;
    5967                };
    6068
     
    6472                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    6573                        /// arguments and return value temporaries
    66                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
     74                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap );
    6775
    6876                        typedef SymTab::Indexer Parent;
    6977                        using Parent::visit;
    7078
     79                        ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {}
     80
    7181                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    72                         virtual void visit( UniqueExpr * unqExpr );
     82                        virtual void visit( UniqueExpr * unqExpr ) override;
     83                        virtual void visit( StmtExpr * stmtExpr ) override;
    7384
    7485                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    7990                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    8091                        void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    81                 private:
     92
    8293                        TypeSubstitution * env;
     94                        const EnvMap & envMap;
    8395                };
    8496
     
    174186                        static void fixInitializers( std::list< Declaration * > &translationUnit );
    175187
    176                         using GenPoly::PolyMutator::mutate;
     188                        typedef GenPoly::PolyMutator Parent;
     189                        using Parent::mutate;
    177190                        virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override;
    178191
     
    186199                        static void fixCopyCtors( std::list< Declaration * > &translationUnit );
    187200
    188                         using GenPoly::PolyMutator::mutate;
     201                        typedef GenPoly::PolyMutator Parent;
     202                        using Parent::mutate;
    189203                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    190204                        virtual Expression * mutate( UniqueExpr * unqExpr ) override;
     205                        virtual Expression * mutate( StmtExpr * stmtExpr ) override;
    191206                };
    192207
     
    248263                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    249264
    250 
    251                 InsertImplicitCalls::insert( translationUnit );
    252                 ResolveCopyCtors::resolveImplicitCalls( translationUnit );
     265                EnvMap envMap;
     266
     267                InsertImplicitCalls::insert( translationUnit, envMap );
     268                ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap );
    253269                InsertDtors::insert( translationUnit );
    254270                FixInit::fixInitializers( translationUnit );
     
    269285
    270286        namespace {
    271                 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
    272                         InsertImplicitCalls inserter;
     287                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
     288                        InsertImplicitCalls inserter( envMap );
    273289                        mutateAll( translationUnit, inserter );
    274290                }
    275291
    276                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) {
    277                         ResolveCopyCtors resolver;
     292                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ) {
     293                        ResolveCopyCtors resolver( envMap );
    278294                        acceptAll( translationUnit, resolver );
    279295                }
     
    326342
    327343                Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    328                         appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
     344                        appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );
    329345                        assert( appExpr );
    330346
     
    339355                                                Type * t1 = ftype->get_parameters().front()->get_type();
    340356                                                Type * t2 = ftype->get_parameters().back()->get_type();
    341                                                 PointerType * ptrType = dynamic_cast< PointerType * > ( t1 );
    342                                                 assert( ptrType );
     357                                                PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 );
    343358
    344359                                                if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
     
    357372                        // wrap each function call so that it is easy to identify nodes that have to be copy constructed
    358373                        ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
    359                         // save the type substitution onto the new node so that it is easy to find.
     374                        // save the type substitution into the envMap so that it is easy to find.
    360375                        // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
    361376                        // The substitution is needed to obtain the type of temporary variables so that copy constructor
     
    366381                        // constructor calls together.
    367382                        assert( env );
    368                         expr->set_env( env );
     383                        envMap[expr] = env;
    369384                        return expr;
     385                }
     386
     387                Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {
     388                        assert( env );
     389                        envMap[stmtExpr] = env;
     390                        return Parent::mutate( stmtExpr );
    370391                }
    371392
     
    392413                        assert( resolved );
    393414                        if ( resolved->get_env() ) {
     415                                // Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes.
    394416                                env->add( *resolved->get_env() );
     417                                delete resolved->get_env();
     418                                resolved->set_env( nullptr );
    395419                        } // if
    396420
     
    401425                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    402426                        static UniqueName tempNamer("_tmp_cp");
    403                         CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
     427                        assert( env );
     428                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; )
    404429                        assert( arg->has_result() );
    405430                        Type * result = arg->get_result();
     
    408433                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
    409434                        result = result->clone();
    410                         impCpCtorExpr->get_env()->apply( result );
     435                        env->apply( result );
    411436                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    412437                        tmp->get_type()->set_isConst( false );
     
    437462                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    438463                        Parent::visit( impCpCtorExpr );
    439                         env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer...
     464                        env = envMap.at(impCpCtorExpr);
     465                        assert( env );
    440466
    441467                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     
    448474                        // each return value from the call needs to be connected with an ObjectDecl at the call site, which is
    449475                        // initialized with the return value and is destructed later
    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() );
     476                        // xxx - handle named return values?
    455477                        Type * result = appExpr->get_result();
    456478                        if ( ! result->isVoid() ) {
    457479                                static UniqueName retNamer("_tmp_cp_ret");
    458480                                result = result->clone();
    459                                 impCpCtorExpr->get_env()->apply( result );
     481                                env->apply( result );
    460482                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    461483                                ret->get_type()->set_isConst( false );
     
    468490                        } // for
    469491                        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
    470519                }
    471520
     
    492541                }
    493542
    494 
    495543                Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    496544                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    497545
    498                         impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) );
    499                         assert( impCpCtorExpr );
    500 
     546                        impCpCtorExpr = safe_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    501547                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    502548                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    558604                                        retExpr = UntypedExpr::createDeref( retExpr );
    559605                                } // if
    560                                 retExpr->set_env( env->clone() );
     606                                // move env from callExpr to retExpr
     607                                retExpr->set_env( callExpr->get_env() );
     608                                callExpr->set_env( nullptr );
    561609                                return retExpr;
    562610                        } else {
     
    565613                }
    566614
     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
    567638                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
    568639                        static std::unordered_map< int, UniqueExpr * > unqMap;
    569640                        static std::unordered_set< int > addDeref;
    570641                        // 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 ) );
    572642                        if ( unqMap.count( unqExpr->get_id() ) ) {
    573643                                // take data from other UniqueExpr to ensure consistency
     
    582652                                return unqExpr;
    583653                        }
     654                        unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    584655                        unqMap[unqExpr->get_id()] = unqExpr;
    585656                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     
    599670                        // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init
    600671                        // is removed from the ObjectDecl
    601                         objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( objDecl ) );
    602 
     672                        objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) );
    603673                        if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    604674                                // a decision should have been made by the resolver, so ctor and init are not both non-NULL
Note: See TracChangeset for help on using the changeset viewer.