Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rb6fe7e6 rf0121d7  
    3535#include "GenPoly/DeclMutator.h"
    3636#include "SynTree/AddStmtVisitor.h"
    37 #include "CodeGen/GenType.h"  // for warnings
    38 
    39 bool ctordtorp = false;
    40 bool ctorp = false;
    41 bool cpctorp = false;
    42 bool dtorp = false;
     37#include "CodeGen/GenType.h"  // for warning/error messages
     38
     39bool ctordtorp = false; // print all debug
     40bool ctorp = false; // print ctor debug
     41bool cpctorp = false; // print copy ctor debug
     42bool dtorp = false; // print dtor debug
    4343#define PRINT( text ) if ( ctordtorp ) { text }
    4444#define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text }
     
    4747namespace InitTweak {
    4848        namespace {
    49                 const std::list<Label> noLabels;
    50                 const std::list<Expression*> noDesignators;
    51 
    5249                class InsertImplicitCalls : public GenPoly::PolyMutator {
    5350                public:
     
    6966
    7067                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    71                         ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     68                        Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     69                        Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
    7270                        /// true if type does not need to be copy constructed to ensure correctness
    73                         bool skipCopyConstruct( Type * );
     71                        bool skipCopyConstruct( Type * type );
     72                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
     73                        void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    7474                private:
    7575                        TypeSubstitution * env;
     
    357357                }
    358358
    359                 ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     359                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    360360                        assert( var );
     361                        return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
     362                }
     363
     364                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
     365                        assert( thisArg );
    361366                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    362                         untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
     367                        untyped->get_args().push_back( thisArg );
    363368                        if (cpArg) untyped->get_args().push_back( cpArg->clone() );
    364369
     
    367372                        // (VariableExpr and already resolved expression)
    368373                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    369                         ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
     374                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
     375                        assert( resolved );
    370376                        if ( resolved->get_env() ) {
    371377                                env->add( *resolved->get_env() );
    372378                        } // if
    373379
    374                         assert( resolved );
    375380                        delete untyped;
    376381                        return resolved;
    377382                }
    378383
     384                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     385                        static UniqueName tempNamer("_tmp_cp");
     386                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
     387                        assert( arg->has_result() );
     388                        Type * result = arg->get_result();
     389                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
     390
     391                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
     392                        result = result->clone();
     393                        impCpCtorExpr->get_env()->apply( result );
     394                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
     395                        tmp->get_type()->set_isConst( false );
     396
     397                        // create and resolve copy constructor
     398                        CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
     399                        Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg );
     400
     401                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) {
     402                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
     403                                // don't create the temporary and don't call the copy constructor
     404                                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     405                                assert( function );
     406                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
     407                        }
     408
     409                        // replace argument to function call with temporary
     410                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
     411                        impCpCtorExpr->get_tempDecls().push_back( tmp );
     412                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     413                }
     414
     415                void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     416                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
     417                }
     418
    379419                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    380                         static UniqueName tempNamer("_tmp_cp");
    381                         static UniqueName retNamer("_tmp_cp_ret");
    382 
    383420                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    384421                        Visitor::visit( impCpCtorExpr );
     
    389426                        // take each argument and attempt to copy construct it.
    390427                        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
     428                                copyConstructArg( arg, impCpCtorExpr );
    416429                        } // for
    417430
     
    423436                        // level. Trying to pass that environment along.
    424437                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    425                         for ( Type * result : appExpr->get_results() ) {
     438                        Type * result = appExpr->get_result();
     439                        if ( ! result->isVoid() ) {
     440                                static UniqueName retNamer("_tmp_cp_ret");
    426441                                result = result->clone();
    427442                                impCpCtorExpr->get_env()->apply( result );
     
    430445                                impCpCtorExpr->get_returnDecls().push_back( ret );
    431446                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    432                                 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
     447                                destructRet( new VariableExpr( ret ) , impCpCtorExpr );
    433448                        } // for
    434449                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
     
    479494                                // know the result type of the assignment is the type of the LHS (minus the pointer), so
    480495                                // add that onto the assignment expression so that later steps have the necessary information
    481                                 assign->add_result( returnDecl->get_type()->clone() );
     496                                assign->set_result( returnDecl->get_type()->clone() );
    482497
    483498                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    484                                 if ( callExpr->get_results().front()->get_isLvalue() ) {
     499                                if ( callExpr->get_result()->get_isLvalue() ) {
    485500                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    486501                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    500515                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
    501516                                        deref->get_args().push_back( retExpr );
    502                                         deref->add_result( resultType );
     517                                        deref->set_result( resultType );
    503518                                        retExpr = deref;
    504519                                } // if
     
    939954                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    940955                        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 );
     956                        // xxx - is the size check necessary?
     957                        assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
     958                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
    943959                        addDeclaration( tmp );
    944960
     
    952968                        assign->get_args().push_back( new VariableExpr( tmp ) );
    953969                        assign->get_args().push_back( firstArg );
    954                         cloneAll( ctorExpr->get_results(), assign->get_results() );
     970                        assign->set_result( ctorExpr->get_result()->clone() );
    955971                        firstArg = assign;
    956972
Note: See TracChangeset for help on using the changeset viewer.