Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rf0121d7 rb6fe7e6  
    3535#include "GenPoly/DeclMutator.h"
    3636#include "SynTree/AddStmtVisitor.h"
    37 #include "CodeGen/GenType.h"  // for warning/error messages
    38 
    39 bool ctordtorp = false; // print all debug
    40 bool ctorp = false; // print ctor debug
    41 bool cpctorp = false; // print copy ctor debug
    42 bool dtorp = false; // print dtor debug
     37#include "CodeGen/GenType.h"  // for warnings
     38
     39bool ctordtorp = false;
     40bool ctorp = false;
     41bool cpctorp = false;
     42bool dtorp = false;
    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
    4952                class InsertImplicitCalls : public GenPoly::PolyMutator {
    5053                public:
     
    6669
    6770                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    68                         Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    69                         Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
     71                        ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    7072                        /// true if type does not need to be copy constructed to ensure correctness
    71                         bool skipCopyConstruct( Type * type );
    72                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    73                         void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
     73                        bool skipCopyConstruct( Type * );
    7474                private:
    7575                        TypeSubstitution * env;
     
    357357                }
    358358
    359                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     359                ApplicationExpr * 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 );
    366361                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    367                         untyped->get_args().push_back( thisArg );
     362                        untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
    368363                        if (cpArg) untyped->get_args().push_back( cpArg->clone() );
    369364
     
    372367                        // (VariableExpr and already resolved expression)
    373368                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    374                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
    375                         assert( resolved );
     369                        ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
    376370                        if ( resolved->get_env() ) {
    377371                                env->add( *resolved->get_env() );
    378372                        } // if
    379373
     374                        assert( resolved );
    380375                        delete untyped;
    381376                        return resolved;
    382377                }
    383378
    384                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     379                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    385380                        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 
    419                 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     381                        static UniqueName retNamer("_tmp_cp_ret");
     382
    420383                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    421384                        Visitor::visit( impCpCtorExpr );
     
    426389                        // take each argument and attempt to copy construct it.
    427390                        for ( Expression * & arg : appExpr->get_args() ) {
    428                                 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
    429416                        } // for
    430417
     
    436423                        // level. Trying to pass that environment along.
    437424                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    438                         Type * result = appExpr->get_result();
    439                         if ( ! result->isVoid() ) {
    440                                 static UniqueName retNamer("_tmp_cp_ret");
     425                        for ( Type * result : appExpr->get_results() ) {
    441426                                result = result->clone();
    442427                                impCpCtorExpr->get_env()->apply( result );
     
    445430                                impCpCtorExpr->get_returnDecls().push_back( ret );
    446431                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    447                                 destructRet( new VariableExpr( ret ) , impCpCtorExpr );
     432                                impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    448433                        } // for
    449434                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
     
    494479                                // know the result type of the assignment is the type of the LHS (minus the pointer), so
    495480                                // add that onto the assignment expression so that later steps have the necessary information
    496                                 assign->set_result( returnDecl->get_type()->clone() );
     481                                assign->add_result( returnDecl->get_type()->clone() );
    497482
    498483                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    499                                 if ( callExpr->get_result()->get_isLvalue() ) {
     484                                if ( callExpr->get_results().front()->get_isLvalue() ) {
    500485                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    501486                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    515500                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
    516501                                        deref->get_args().push_back( retExpr );
    517                                         deref->set_result( resultType );
     502                                        deref->add_result( resultType );
    518503                                        retExpr = deref;
    519504                                } // if
     
    954939                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    955940                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    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 );
     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 );
    959943                        addDeclaration( tmp );
    960944
     
    968952                        assign->get_args().push_back( new VariableExpr( tmp ) );
    969953                        assign->get_args().push_back( firstArg );
    970                         assign->set_result( ctorExpr->get_result()->clone() );
     954                        cloneAll( ctorExpr->get_results(), assign->get_results() );
    971955                        firstArg = assign;
    972956
Note: See TracChangeset for help on using the changeset viewer.