Changeset bcc0946


Ignore:
Timestamp:
Aug 31, 2018, 9:27:38 AM (3 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
029e330
Parents:
2bfc6b2
Message:

Minor code cleanup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r2bfc6b2 rbcc0946  
    255255                GenStructMemberCalls::generate( translationUnit );
    256256
    257                 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
    258                 // hack in the way untyped assignments are generated, where the first argument cannot have
    259                 // its address taken because of the way codegeneration handles UntypedExpr vs. ApplicationExpr.
    260                 // Thus such assignment exprs must never pushed through expression resolution (and thus should
    261                 // not go through the FixCopyCtors pass), otherwise they will fail -- guaranteed.
    262                 // Also needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
    263                 // don't look right, and a member can be constructed more than once.
     257                // Needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
     258                // don't have the correct form, and a member can be constructed more than once.
    264259                FixCtorExprs::fix( translationUnit );
    265260        }
    266261
    267262        namespace {
     263                /// find and return the destructor used in `input`. If `input` is not a simple destructor call, generate a thunk
     264                /// that wraps the destructor, insert it into `stmtsToAdd` and return the new function declaration
     265                DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * input, std::list< Statement * > & stmtsToAdd ) {
     266                        // unwrap implicit statement wrapper
     267                        Statement * dtor = input;
     268                        if ( ImplicitCtorDtorStmt * implicit = dynamic_cast< ImplicitCtorDtorStmt * >( input ) ) {
     269                                // dtor = implicit->callStmt;
     270                                // implicit->callStmt = nullptr;
     271                        }
     272                        assert( dtor );
     273                        std::list< Expression * > matches;
     274                        collectCtorDtorCalls( dtor, matches );
     275
     276                        if ( dynamic_cast< ExprStmt * >( dtor ) ) {
     277                                // only one destructor call in the expression
     278                                if ( matches.size() == 1 ) {
     279                                        DeclarationWithType * func = getFunction( matches.front() );
     280                                        assertf( func, "getFunction failed to find function in %s", toString( matches.front() ).c_str() );
     281
     282                                        // cleanup argument must be a function, not an object (including function pointer)
     283                                        if ( FunctionDecl * dtorFunc = dynamic_cast< FunctionDecl * > ( func ) ) {
     284                                                if ( dtorFunc->type->forall.empty() ) {
     285                                                        // simple case where the destructor is a monomorphic function call - can simply
     286                                                        // use that function as the cleanup function.
     287                                                        delete dtor;
     288                                                        return func;
     289                                                }
     290                                        }
     291                                }
     292                        }
     293
     294                        // otherwise the cleanup is more complicated - need to build a single argument cleanup function that
     295                        // wraps the more complicated code.
     296                        static UniqueName dtorNamer( "__cleanup_dtor" );
     297                        FunctionDecl * dtorFunc = FunctionDecl::newFunction( dtorNamer.newName(), SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt() );
     298                        stmtsToAdd.push_back( new DeclStmt( dtorFunc ) );
     299
     300                        // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
     301                        ObjectDecl * thisParam = getParamThis( dtorFunc->type );
     302                        Expression * replacement = new VariableExpr( thisParam );
     303
     304                        Type * base = replacement->result->stripReferences();
     305                        if ( dynamic_cast< ArrayType * >( base ) || dynamic_cast< TupleType * > ( base ) ) {
     306                                // need to cast away reference for array types, since the destructor is generated without the reference type,
     307                                // and for tuple types since tuple indexing does not work directly on a reference
     308                                replacement = new CastExpr( replacement, base->clone() );
     309                        }
     310                        DeclReplacer::replace( dtor, { std::make_pair( objDecl, replacement ) } );
     311                        dtorFunc->statements->push_back( strict_dynamic_cast<Statement *>( dtor ) );
     312
     313                        return dtorFunc;
     314                }
     315
    268316                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
    269317                        PassVisitor<InsertImplicitCalls> inserter;
     
    602650
    603651                        // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    604                         assert( unqExpr->get_result() );
    605                         if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) {
     652                        assert( unqExpr->result );
     653                        if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->expr ) ) {
    606654                                // note the variable used as the result from the call
    607                                 assert( impCpCtorExpr->get_result() && impCpCtorExpr->get_returnDecls().size() == 1 );
    608                                 unqExpr->set_var( new VariableExpr( impCpCtorExpr->get_returnDecls().front() ) );
     655                                assert( impCpCtorExpr->result && impCpCtorExpr->returnDecls.size() == 1 );
     656                                unqExpr->set_var( new VariableExpr( impCpCtorExpr->returnDecls.front() ) );
    609657                        } else {
    610658                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    611                                 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), makeInit( unqExpr->get_result() ) ) );
    612                                 unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
     659                                unqExpr->object = ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->result->clone(), makeInit( unqExpr->result ) );
     660                                unqExpr->var = new VariableExpr( unqExpr->object );
    613661                        }
    614662                        vars.insert( unqExpr->get_id() );
     
    618666                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    619667
    620                         std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    621                         std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
    622                         std::list< Expression * > & dtors = impCpCtorExpr->get_dtors();
     668                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->tempDecls;
     669                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->returnDecls;
     670                        std::list< Expression * > & dtors = impCpCtorExpr->dtors;
    623671
    624672                        // add all temporary declarations and their constructors
     
    647695                        tempDecls.clear();
    648696                        returnDecls.clear();
    649                         impCpCtorExpr->set_callExpr( nullptr );
     697                        impCpCtorExpr->callExpr = nullptr;
    650698                        std::swap( impCpCtorExpr->env, callExpr->env );
    651699                        assert( impCpCtorExpr->env == nullptr );
     
    730778                }
    731779
    732                 DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * input, std::list< Statement * > & stmtsToAdd ) {
    733                         // unwrap implicit statement wrapper
    734                         Statement * dtor = input;
    735                         if ( ImplicitCtorDtorStmt * implicit = dynamic_cast< ImplicitCtorDtorStmt * >( input ) ) {
    736                                 // dtor = implicit->callStmt;
    737                                 // implicit->callStmt = nullptr;
    738                         }
    739                         assert( dtor );
    740                         std::list< Expression * > matches;
    741                         collectCtorDtorCalls( dtor, matches );
    742 
    743                         if ( dynamic_cast< ExprStmt * >( dtor ) ) {
    744                                 // only one destructor call in the expression
    745                                 if ( matches.size() == 1 ) {
    746                                         DeclarationWithType * func = getFunction( matches.front() );
    747                                         assertf( func, "getFunction failed to find function in %s", toString( matches.front() ).c_str() );
    748 
    749                                         // cleanup argument must be a function, not an object (including function pointer)
    750                                         if ( FunctionDecl * dtorFunc = dynamic_cast< FunctionDecl * > ( func ) ) {
    751                                                 if ( dtorFunc->type->forall.empty() ) {
    752                                                         // simple case where the destructor is a monomorphic function call - can simply
    753                                                         // use that function as the cleanup function.
    754                                                         delete dtor;
    755                                                         return func;
    756                                                 }
    757                                         }
    758                                 }
    759                         }
    760 
    761                         // otherwise the cleanup is more complicated - need to build a single argument cleanup function that
    762                         // wraps the more complicated code.
    763                         static UniqueName dtorNamer( "__cleanup_dtor" );
    764                         FunctionDecl * dtorFunc = FunctionDecl::newFunction( dtorNamer.newName(), SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt() );
    765                         stmtsToAdd.push_back( new DeclStmt( dtorFunc ) );
    766 
    767                         // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
    768                         ObjectDecl * thisParam = getParamThis( dtorFunc->type );
    769                         Expression * replacement = new VariableExpr( thisParam );
    770 
    771                         Type * base = replacement->result->stripReferences();
    772                         if ( dynamic_cast< ArrayType * >( base ) || dynamic_cast< TupleType * > ( base ) ) {
    773                                 // need to cast away reference for array types, since the destructor is generated without the reference type,
    774                                 // and for tuple types since tuple indexing does not work directly on a reference
    775                                 replacement = new CastExpr( replacement, base->clone() );
    776                         }
    777                         DeclReplacer::replace( dtor, { std::make_pair( objDecl, replacement ) } );
    778                         dtorFunc->statements->push_back( strict_dynamic_cast<Statement *>( dtor ) );
    779 
    780                         return dtorFunc;
    781                 }
    782 
    783780                DeclarationWithType * FixInit::postmutate( ObjectDecl *objDecl ) {
    784781                        // since this removes the init field from objDecl, it must occur after children are mutated (i.e. postmutate)
Note: See TracChangeset for help on using the changeset viewer.