Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rb6fe7e6 r65660bd  
    6969
    7070                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    71                         ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     71                        Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     72                        Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
    7273                        /// true if type does not need to be copy constructed to ensure correctness
    73                         bool skipCopyConstruct( Type * );
     74                        bool skipCopyConstruct( Type * type );
     75                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
     76                        void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    7477                private:
    7578                        TypeSubstitution * env;
     
    357360                }
    358361
    359                 ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     362                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    360363                        assert( var );
     364                        return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
     365                }
     366
     367                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
     368                        assert( thisArg );
    361369                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    362                         untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
     370                        untyped->get_args().push_back( thisArg );
    363371                        if (cpArg) untyped->get_args().push_back( cpArg->clone() );
    364372
     
    367375                        // (VariableExpr and already resolved expression)
    368376                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    369                         ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
     377                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
     378                        assert( resolved );
    370379                        if ( resolved->get_env() ) {
    371380                                env->add( *resolved->get_env() );
    372381                        } // if
    373382
    374                         assert( resolved );
    375383                        delete untyped;
    376384                        return resolved;
    377385                }
    378386
     387                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     388                        static UniqueName tempNamer("_tmp_cp");
     389                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
     390                        assert( arg->has_result() );
     391                        Type * result = arg->get_result();
     392                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
     393
     394                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
     395                        result = result->clone();
     396                        impCpCtorExpr->get_env()->apply( result );
     397                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
     398                        tmp->get_type()->set_isConst( false );
     399
     400                        // create and resolve copy constructor
     401                        CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
     402                        Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg );
     403
     404                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) {
     405                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
     406                                // don't create the temporary and don't call the copy constructor
     407                                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     408                                assert( function );
     409                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
     410                        }
     411
     412                        // replace argument to function call with temporary
     413                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
     414                        impCpCtorExpr->get_tempDecls().push_back( tmp );
     415                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     416                }
     417
     418                void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     419                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
     420                }
     421
    379422                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    380                         static UniqueName tempNamer("_tmp_cp");
    381                         static UniqueName retNamer("_tmp_cp_ret");
    382 
    383423                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    384424                        Visitor::visit( impCpCtorExpr );
     
    389429                        // take each argument and attempt to copy construct it.
    390430                        for ( Expression * & arg : appExpr->get_args() ) {
    391                                 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
    392                                 // xxx - need to handle tuple arguments
    393                                 assert( ! arg->get_results().empty() );
    394                                 Type * result = arg->get_results().front();
    395                                 if ( skipCopyConstruct( result ) ) continue; // skip certain non-copyable types
    396                                 // type may involve type variables, so apply type substitution to get temporary variable's actual type
    397                                 result = result->clone();
    398                                 impCpCtorExpr->get_env()->apply( result );
    399                                 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
    400                                 tmp->get_type()->set_isConst( false );
    401 
    402                                 // create and resolve copy constructor
    403                                 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
    404                                 ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg );
    405 
    406                                 // if the chosen constructor is intrinsic, the copy is unnecessary, so
    407                                 // don't create the temporary and don't call the copy constructor
    408                                 VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() );
    409                                 assert( function );
    410                                 if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) {
    411                                         // replace argument to function call with temporary
    412                                         arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    413                                         impCpCtorExpr->get_tempDecls().push_back( tmp );
    414                                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
    415                                 } // if
     431                                copyConstructArg( arg, impCpCtorExpr );
    416432                        } // for
    417433
     
    423439                        // level. Trying to pass that environment along.
    424440                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    425                         for ( Type * result : appExpr->get_results() ) {
     441                        Type * result = appExpr->get_result();
     442                        if ( ! result->isVoid() ) {
     443                                static UniqueName retNamer("_tmp_cp_ret");
    426444                                result = result->clone();
    427445                                impCpCtorExpr->get_env()->apply( result );
     
    430448                                impCpCtorExpr->get_returnDecls().push_back( ret );
    431449                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    432                                 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
     450                                destructRet( new VariableExpr( ret ) , impCpCtorExpr );
    433451                        } // for
    434452                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
     
    479497                                // know the result type of the assignment is the type of the LHS (minus the pointer), so
    480498                                // add that onto the assignment expression so that later steps have the necessary information
    481                                 assign->add_result( returnDecl->get_type()->clone() );
     499                                assign->set_result( returnDecl->get_type()->clone() );
    482500
    483501                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    484                                 if ( callExpr->get_results().front()->get_isLvalue() ) {
     502                                if ( callExpr->get_result()->get_isLvalue() ) {
    485503                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    486504                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    500518                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
    501519                                        deref->get_args().push_back( retExpr );
    502                                         deref->add_result( resultType );
     520                                        deref->set_result( resultType );
    503521                                        retExpr = deref;
    504522                                } // if
     
    939957                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    940958                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    941                         assert( ctorExpr->get_results().size() == 1 );
    942                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr );
     959                        assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
     960                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
    943961                        addDeclaration( tmp );
    944962
     
    952970                        assign->get_args().push_back( new VariableExpr( tmp ) );
    953971                        assign->get_args().push_back( firstArg );
    954                         cloneAll( ctorExpr->get_results(), assign->get_results() );
     972                        assign->set_result( ctorExpr->get_result()->clone() );
    955973                        firstArg = assign;
    956974
Note: See TracChangeset for help on using the changeset viewer.