Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r65660bd rb6fe7e6  
    6969
    7070                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    71                         Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    72                         Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
     71                        ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    7372                        /// true if type does not need to be copy constructed to ensure correctness
    74                         bool skipCopyConstruct( Type * type );
    75                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    76                         void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
     73                        bool skipCopyConstruct( Type * );
    7774                private:
    7875                        TypeSubstitution * env;
     
    360357                }
    361358
    362                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     359                ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    363360                        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 );
    369361                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    370                         untyped->get_args().push_back( thisArg );
     362                        untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
    371363                        if (cpArg) untyped->get_args().push_back( cpArg->clone() );
    372364
     
    375367                        // (VariableExpr and already resolved expression)
    376368                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    377                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
    378                         assert( resolved );
     369                        ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
    379370                        if ( resolved->get_env() ) {
    380371                                env->add( *resolved->get_env() );
    381372                        } // if
    382373
     374                        assert( resolved );
    383375                        delete untyped;
    384376                        return resolved;
    385377                }
    386378
    387                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     379                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    388380                        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 
    422                 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     381                        static UniqueName retNamer("_tmp_cp_ret");
     382
    423383                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    424384                        Visitor::visit( impCpCtorExpr );
     
    429389                        // take each argument and attempt to copy construct it.
    430390                        for ( Expression * & arg : appExpr->get_args() ) {
    431                                 copyConstructArg( arg, impCpCtorExpr );
     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
    432416                        } // for
    433417
     
    439423                        // level. Trying to pass that environment along.
    440424                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    441                         Type * result = appExpr->get_result();
    442                         if ( ! result->isVoid() ) {
    443                                 static UniqueName retNamer("_tmp_cp_ret");
     425                        for ( Type * result : appExpr->get_results() ) {
    444426                                result = result->clone();
    445427                                impCpCtorExpr->get_env()->apply( result );
     
    448430                                impCpCtorExpr->get_returnDecls().push_back( ret );
    449431                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    450                                 destructRet( new VariableExpr( ret ) , impCpCtorExpr );
     432                                impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    451433                        } // for
    452434                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
     
    497479                                // know the result type of the assignment is the type of the LHS (minus the pointer), so
    498480                                // add that onto the assignment expression so that later steps have the necessary information
    499                                 assign->set_result( returnDecl->get_type()->clone() );
     481                                assign->add_result( returnDecl->get_type()->clone() );
    500482
    501483                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    502                                 if ( callExpr->get_result()->get_isLvalue() ) {
     484                                if ( callExpr->get_results().front()->get_isLvalue() ) {
    503485                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    504486                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    518500                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
    519501                                        deref->get_args().push_back( retExpr );
    520                                         deref->set_result( resultType );
     502                                        deref->add_result( resultType );
    521503                                        retExpr = deref;
    522504                                } // if
     
    957939                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    958940                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    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 );
     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 );
    961943                        addDeclaration( tmp );
    962944
     
    970952                        assign->get_args().push_back( new VariableExpr( tmp ) );
    971953                        assign->get_args().push_back( firstArg );
    972                         assign->set_result( ctorExpr->get_result()->clone() );
     954                        cloneAll( ctorExpr->get_results(), assign->get_results() );
    973955                        firstArg = assign;
    974956
Note: See TracChangeset for help on using the changeset viewer.