Ignore:
Timestamp:
Oct 19, 2017, 12:01:04 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
837ce06
Parents:
b96ec83 (diff), a15b72c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rb96ec83 r6840e7c  
    9494                        /// true if type does not need to be copy constructed to ensure correctness
    9595                        bool skipCopyConstruct( Type * type );
    96                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
     96                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal );
    9797                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    9898
     
    259259
    260260                GenStructMemberCalls::generate( translationUnit );
     261
    261262                // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
    262263                // hack in the way untyped assignments are generated, where the first argument cannot have
     
    288289                        for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    289290                                try {
    290                                         *i = maybeMutate( *i, fixer );
     291                                        maybeMutate( *i, fixer );
    291292                                        translationUnit.splice( i, fixer.pass.staticDtorDecls );
    292293                                } catch( SemanticError &e ) {
     
    322323
    323324                Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
    324                         assert( appExpr );
    325 
    326325                        if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
    327                                 if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() ) ) {
     326                                if ( function->var->linkage.is_builtin ) {
    328327                                        // optimization: don't need to copy construct in order to call intrinsic functions
    329328                                        return appExpr;
     
    331330                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    332331                                        assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
    333                                         if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
    334                                                 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
    335                                                 Type * t2 = ftype->get_parameters().back()->get_type();
     332                                        if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->parameters.size() == 2 ) {
     333                                                Type * t1 = getPointerBase( ftype->parameters.front()->get_type() );
     334                                                Type * t2 = ftype->parameters.back()->get_type();
    336335                                                assert( t1 );
    337336
     
    366365                        ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
    367366                        ExprStmt * exprStmt = strict_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
    368                         Expression * untyped = exprStmt->get_expr();
     367                        Expression * resolved = exprStmt->expr;
     368                        exprStmt->expr = nullptr; // take ownership of expr
    369369
    370370                        // resolve copy constructor
    371371                        // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed
    372372                        // (VariableExpr and already resolved expression)
    373                         CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    374                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );
     373                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << resolved << std::endl; )
     374                        ResolvExpr::findVoidExpression( resolved, indexer );
    375375                        assert( resolved );
    376376                        if ( resolved->get_env() ) {
     
    380380                                resolved->set_env( nullptr );
    381381                        } // if
    382 
    383382                        delete stmt;
    384383                        return resolved;
    385384                }
    386385
    387                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     386                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) {
    388387                        static UniqueName tempNamer("_tmp_cp");
    389388                        assert( env );
    390389                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; )
    391                         assert( arg->has_result() );
    392                         Type * result = arg->get_result();
     390                        assert( arg->result );
     391                        Type * result = arg->result;
    393392                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
    394393
    395                         // type may involve type variables, so apply type substitution to get temporary variable's actual type
     394                        // type may involve type variables, so apply type substitution to get temporary variable's actual type.
     395                        // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T).
    396396                        result = result->clone();
    397                         env->apply( result );
     397                        env->applyFree( result );
    398398                        ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
    399399                        tmp->get_type()->set_const( false );
     
    406406                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
    407407                                // don't create the temporary and don't call the copy constructor
    408                                 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
    409                                 assert( function );
    410                                 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
     408                                VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function );
     409                                if ( function->var->linkage == LinkageSpec::Intrinsic ) {
     410                                        // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic,
     411                                        // so that the object isn't changed inside of the polymorphic function
     412                                        if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return;
     413                                }
    411414                        }
    412415
     
    416419                        // replace argument to function call with temporary
    417420                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    418                         impCpCtorExpr->get_tempDecls().push_back( tmp );
    419                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     421                        impCpCtorExpr->tempDecls.push_back( tmp );
     422                        impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) );
    420423                }
    421424
     
    427430                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    428431
    429                         ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     432                        ApplicationExpr * appExpr = impCpCtorExpr->callExpr;
    430433
    431434                        // take each argument and attempt to copy construct it.
    432                         for ( Expression * & arg : appExpr->get_args() ) {
    433                                 copyConstructArg( arg, impCpCtorExpr );
     435                        FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result );
     436                        assert( ftype );
     437                        auto & params = ftype->parameters;
     438                        auto iter = params.begin();
     439                        for ( Expression * & arg : appExpr->args ) {
     440                                Type * formal = nullptr;
     441                                if ( iter != params.end() ) {
     442                                        DeclarationWithType * param = *iter++;
     443                                        formal = param->get_type();
     444                                }
     445
     446                                copyConstructArg( arg, impCpCtorExpr, formal );
    434447                        } // for
    435448
     
    437450                        // initialized with the return value and is destructed later
    438451                        // xxx - handle named return values?
    439                         Type * result = appExpr->get_result();
     452                        Type * result = appExpr->result;
    440453                        if ( ! result->isVoid() ) {
    441454                                static UniqueName retNamer("_tmp_cp_ret");
     
    443456                                env->apply( result );
    444457                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    445                                 ret->get_type()->set_const( false );
    446                                 impCpCtorExpr->get_returnDecls().push_back( ret );
     458                                ret->type->set_const( false );
     459                                impCpCtorExpr->returnDecls.push_back( ret );
    447460                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    448461                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
     
    551564                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    552565                                // move env from callExpr to retExpr
    553                                 retExpr->set_env( callExpr->get_env() );
    554                                 callExpr->set_env( nullptr );
     566                                std::swap( retExpr->env, callExpr->env );
    555567                                return retExpr;
    556568                        } else {
     
    754766                                                if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->expr )) && ctorCall->get_args().size() == 2 ) {
    755767                                                        // clean up intrinsic copy constructor calls by making them into SingleInits
    756                                                         objDecl->init = new SingleInit( ctorCall->args.back() );
     768                                                        Expression * ctorArg = ctorCall->args.back();
     769                                                        std::swap( ctorArg->env, ctorCall->env );
     770                                                        objDecl->init = new SingleInit( ctorArg );
     771
    757772                                                        ctorCall->args.pop_back();
    758773                                                } else {
     
    822837                        GuardValue( labelVars );
    823838                        labelVars.clear();
     839                        // LabelFinder does not recurse into FunctionDecl, so need to visit
     840                        // its children manually.
    824841                        maybeAccept( funcDecl->type, finder );
    825842                        maybeAccept( funcDecl->statements, finder );
     
    10791096                }
    10801097
    1081                 DeclarationWithType * MutatingResolver::mutate( ObjectDecl *objectDecl ) {
     1098                DeclarationWithType * MutatingResolver::mutate( ObjectDecl * objectDecl ) {
    10821099                        // add object to the indexer assumes that there will be no name collisions
    10831100                        // in generated code. If this changes, add mutate methods for entities with
     
    10871104                }
    10881105
    1089                 Expression* MutatingResolver::mutate( UntypedExpr *untypedExpr ) {
    1090                         return strict_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) );
     1106                Expression * MutatingResolver::mutate( UntypedExpr * untypedExpr ) {
     1107                        Expression * newExpr = untypedExpr;
     1108                        ResolvExpr::findVoidExpression( newExpr, indexer );
     1109                        return newExpr;
    10911110                }
    10921111
     
    10941113                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    10951114                        // xxx - is the size check necessary?
    1096                         assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
     1115                        assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 );
    10971116
    10981117                        // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
     
    11131132
    11141133                        // resolve assignment and dispose of new env
    1115                         Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
    1116                         delete resolvedAssign->env;
    1117                         resolvedAssign->env = nullptr;
    1118                         delete assign;
     1134                        ResolvExpr::findVoidExpression( assign, indexer );
     1135                        delete assign->env;
     1136                        assign->env = nullptr;
    11191137
    11201138                        // for constructor expr:
     
    11251143                        //   T & tmp;
    11261144                        //   &tmp = &x, ?{}(tmp), tmp
    1127                         CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1145                        CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11281146                        commaExpr->set_env( env );
    11291147                        return commaExpr;
Note: See TracChangeset for help on using the changeset viewer.