Changeset 1132b62


Ignore:
Timestamp:
Sep 20, 2016, 7:14:15 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
65660bd
Parents:
23b6643f
Message:

copy construct tuple function arguments, and destruct tuple function results

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r23b6643f r1132b62  
    7070                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    7171                        ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     72                        ApplicationExpr * 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;
     
    359362                ApplicationExpr * 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                ApplicationExpr * 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
     
    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                        if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( arg ) ) {
     395                                for ( Expression * & expr : tupleExpr->get_exprs() ) {
     396                                        copyConstructArg( expr, impCpCtorExpr );
     397                                }
     398                                return;
     399                        }
     400
     401                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
     402                        result = result->clone();
     403                        impCpCtorExpr->get_env()->apply( result );
     404                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
     405                        tmp->get_type()->set_isConst( false );
     406
     407                        // create and resolve copy constructor
     408                        CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; )
     409                        ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg );
     410
     411                        // if the chosen constructor is intrinsic, the copy is unnecessary, so
     412                        // don't create the temporary and don't call the copy constructor
     413                        VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() );
     414                        assert( function );
     415                        if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) {
     416                                // replace argument to function call with temporary
     417                                arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
     418                                impCpCtorExpr->get_tempDecls().push_back( tmp );
     419                                impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     420                        } // if
     421                }
     422
     423                void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     424                        if ( TupleType * tupleType = dynamic_cast< TupleType * > ( ret->get_result() ) ) {
     425                                int idx = 0;
     426                                for ( Type *& t : tupleType->get_types() ) {
     427                                        (void)t;
     428                                        destructRet( new TupleIndexExpr( ret->clone(), idx++ ), impCpCtorExpr );
     429                                }
     430                                return;
     431                        }
     432                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
     433                }
     434
    379435                void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    380                         static UniqueName tempNamer("_tmp_cp");
    381                         static UniqueName retNamer("_tmp_cp_ret");
    382 
    383436                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    384437                        Visitor::visit( impCpCtorExpr );
     
    389442                        // take each argument and attempt to copy construct it.
    390443                        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->has_result() );
    394                                 Type * result = arg->get_result();
    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
     444                                copyConstructArg( arg, impCpCtorExpr );
    416445                        } // for
    417446
     
    425454                        Type * result = appExpr->get_result();
    426455                        if ( ! result->isVoid() ) {
    427                                 // need to flatten result type and construct each
     456                                static UniqueName retNamer("_tmp_cp_ret");
    428457                                result = result->clone();
    429458                                impCpCtorExpr->get_env()->apply( result );
     
    432461                                impCpCtorExpr->get_returnDecls().push_back( ret );
    433462                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    434                                 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
     463                                destructRet( new VariableExpr( ret ) , impCpCtorExpr );
    435464                        } // for
    436465                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
  • src/SynTree/TupleExpr.cc

    r23b6643f r1132b62  
    4646        assert( type->size() > index );
    4747        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
     48        get_result()->set_isLvalue( type->get_isLvalue() );
    4849}
    4950
  • src/Tuples/TupleExpansion.cc

    r23b6643f r1132b62  
    2727#include "SymTab/Mangler.h"
    2828#include "Common/ScopedMap.h"
     29#include "ResolvExpr/typeops.h"
    2930
    3031namespace Tuples {
     
    4849
    4950                        virtual Type * mutate( TupleType * tupleType );
     51                        virtual Type * mutate( FunctionType * ftype );
    5052
    5153                        virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
     
    119121        }
    120122
     123        Type * TupleTypeReplacer::mutate( FunctionType * ftype ) {
     124                // replace multiple-returning functions with functions which return a tuple
     125                if ( ftype->get_returnVals().size() > 1 ) {
     126                        TupleType * tupleType = safe_dynamic_cast<TupleType *>( ResolvExpr::extractResultType( ftype ) );
     127                        ObjectDecl * retVal = new ObjectDecl( "__tuple_ret", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, tupleType, nullptr );
     128                        // xxx - replace all uses of return vals with appropriate tuple index expr
     129                        deleteAll( ftype->get_returnVals() );
     130                        ftype->get_returnVals().clear();
     131                        ftype->get_returnVals().push_back( retVal );
     132                }
     133                return Parent::mutate( ftype );
     134        }
     135
    121136        Type * TupleTypeReplacer::mutate( TupleType * tupleType ) {
    122137                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
  • src/main.cc

    r23b6643f r1132b62  
    269269                OPTPRINT( "convertLvalue" )
    270270                GenPoly::convertLvalue( translationUnit );
     271
     272                if ( bboxp ) {
     273                        dump( translationUnit );
     274                        return 0;
     275                } // if
     276                OPTPRINT( "box" )
     277                GenPoly::box( translationUnit );
    271278                OPTPRINT( "expandTuples" ); // xxx - is this the right place for this?
    272279                Tuples::expandTuples( translationUnit );
    273 
    274                 if ( bboxp ) {
    275                         dump( translationUnit );
    276                         return 0;
    277                 } // if
    278                 OPTPRINT( "box" )
    279                 GenPoly::box( translationUnit );
    280280
    281281                // print tree right before code generation
Note: See TracChangeset for help on using the changeset viewer.