Changeset 65660bd for src/InitTweak


Ignore:
Timestamp:
Sep 22, 2016, 8:14:56 AM (9 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:
ac9ca96
Parents:
1132b62
git-author:
Rob Schluntz <rschlunt@…> (09/21/16 23:43:37)
git-committer:
Rob Schluntz <rschlunt@…> (09/22/16 08:14:56)
Message:

replace multiple-returning functions with tuple-returning functions, implement tuple ctor/dtor, allow N-arg tuple assignment

Location:
src/InitTweak
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/InitTweak/FixInit.cc

    r1132b62 r65660bd  
    6969
    7070                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    71                         ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    72                         ApplicationExpr * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
     71                        Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
     72                        Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
    7373                        /// true if type does not need to be copy constructed to ensure correctness
    7474                        bool skipCopyConstruct( Type * type );
     
    360360                }
    361361
    362                 ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     362                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    363363                        assert( var );
    364364                        return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
    365365                }
    366366
    367                 ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
     367                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
    368368                        assert( thisArg );
    369369                        UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
     
    375375                        // (VariableExpr and already resolved expression)
    376376                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    377                         ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
     377                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
     378                        assert( resolved );
    378379                        if ( resolved->get_env() ) {
    379380                                env->add( *resolved->get_env() );
    380381                        } // if
    381382
    382                         assert( resolved );
    383383                        delete untyped;
    384384                        return resolved;
     
    392392                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
    393393
    394                         if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( arg ) ) {
    395                                 for ( Expression * & expr : tupleExpr->get_exprs() ) {
    396                                         copyConstructArg( expr, impCpCtorExpr );
    397                                 }
    398                                 return;
    399                         }
    400 
    401394                        // type may involve type variables, so apply type substitution to get temporary variable's actual type
    402395                        result = result->clone();
     
    407400                        // create and resolve copy constructor
    408401                        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
     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 ) );
    421416                }
    422417
    423418                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                         }
    432419                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
    433420                }
  • TabularUnified src/InitTweak/GenInit.cc

    r1132b62 r65660bd  
    2929#include "GenPoly/DeclMutator.h"
    3030#include "GenPoly/ScopedSet.h"
     31#include "ResolvExpr/typeops.h"
    3132
    3233namespace InitTweak {
     
    5051
    5152          protected:
    52                 std::list<DeclarationWithType*> returnVals;
     53                FunctionType * ftype;
    5354                UniqueName tempNamer;
    5455                std::string funcName;
     
    8687
    8788                bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
     89                bool isManaged( Type * type ) const; // determine if type is managed
    8890                void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
    8991                GenPoly::ScopedSet< std::string > managedTypes;
     
    134136
    135137        Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
    136                 // update for multiple return values
     138                std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
    137139                assert( returnVals.size() == 0 || returnVals.size() == 1 );
    138140                // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
     
    156158
    157159        DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    158                 ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals );
     160                // xxx - need to handle named return values - this pass may need to happen
     161                // after resolution? the ordering is tricky because return statements must be
     162                // constructed - the simplest way to do that (while also handling multiple
     163                // returns) is to structure the returnVals into a tuple, as done here.
     164                // however, if the tuple return value is structured before resolution,
     165                // it's difficult to resolve named return values, since the name is lost
     166                // in conversion to a tuple. this might be easiest to deal with
     167                // after reference types are added, as it may then be possible to
     168                // uniformly move named return values to the parameter list directly
     169                ValueGuard< FunctionType * > oldFtype( ftype );
    159170                ValueGuard< std::string > oldFuncName( funcName );
    160171
    161                 FunctionType * type = functionDecl->get_functionType();
    162                 returnVals = type->get_returnVals();
     172                ftype = functionDecl->get_functionType();
     173                std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
     174                if ( retVals.size() > 1 ) {
     175                        TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
     176                        ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
     177                        retVals.clear();
     178                        retVals.push_back( newRet );
     179                }
    163180                funcName = functionDecl->get_name();
    164181                DeclarationWithType * decl = Mutator::mutate( functionDecl );
     
    220237        }
    221238
     239        bool CtorDtor::isManaged( Type * type ) const {
     240                return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();
     241        }
     242
    222243        bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
    223244                Type * type = objDecl->get_type();
     
    225246                        type = at->get_base();
    226247                }
    227                 return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();
     248                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
     249                        return std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); });
     250                }
     251                return isManaged( type );
    228252        }
    229253
Note: See TracChangeset for help on using the changeset viewer.