Changeset 2162c2c for src/Tuples


Ignore:
Timestamp:
Jan 11, 2017, 4:11:02 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
075734f
Parents:
bb82c03 (diff), d3a85240 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/Tuples
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    rbb82c03 r2162c2c  
    3333        /// helper function used by explode
    3434        template< typename OutputIterator >
    35         void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out ) {
     35        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
     36                if ( isTupleAssign ) {
     37                        // tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
     38                        if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
     39                                ResolvExpr::AltList alts;
     40                                explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     41                                for ( ResolvExpr::Alternative & alt : alts ) {
     42                                        // distribute '&' over all components
     43                                        alt.expr = distributeAddr( alt.expr );
     44                                        *out++ = alt;
     45                                }
     46                                // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
     47                                return;
     48                        }
     49                }
    3650                Type * res = expr->get_result();
    37                 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
    38                         ResolvExpr::AltList alts;
    39                         explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ) );
    40                         for ( ResolvExpr::Alternative & alt : alts ) {
    41                                 // distribute '&' over all components
    42                                 alt.expr = distributeAddr( alt.expr );
    43                                 *out++ = alt;
    44                         }
    45                 } else if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
     51                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
    4652                        if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) {
    4753                                // can open tuple expr and dump its exploded components
    4854                                for ( Expression * expr : tupleExpr->get_exprs() ) {
    49                                         explodeUnique( expr, alt, indexer, out );
     55                                        explodeUnique( expr, alt, indexer, out, isTupleAssign );
    5056                                }
    5157                        } else {
     
    5864                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
    5965                                        TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
    60                                         explodeUnique( idx, alt, indexer, out );
     66                                        explodeUnique( idx, alt, indexer, out, isTupleAssign );
    6167                                        delete idx;
    6268                                }
     
    7177        /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
    7278        template< typename OutputIterator >
    73         void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out ) {
    74                 explodeUnique( alt.expr, alt, indexer, out );
     79        void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
     80                explodeUnique( alt.expr, alt, indexer, out, isTupleAssign );
    7581        }
    7682
    7783        // explode list of alternatives
    7884        template< typename AltIterator, typename OutputIterator >
    79         void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out ) {
     85        void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
    8086                for ( ; altBegin != altEnd; ++altBegin ) {
    81                         explode( *altBegin, indexer, out );
     87                        explode( *altBegin, indexer, out, isTupleAssign );
    8288                }
    8389        }
    8490
    8591        template< typename OutputIterator >
    86         void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out ) {
    87                 explode( alts.begin(), alts.end(), indexer, out );
     92        void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) {
     93                explode( alts.begin(), alts.end(), indexer, out, isTupleAssign );
    8894        }
    8995} // namespace Tuples
  • src/Tuples/TupleAssignment.cc

    rbb82c03 r2162c2c  
    7373        };
    7474
    75         /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
     75        /// true if expr is an expression of tuple type
    7676        bool isTuple( Expression *expr ) {
    7777                if ( ! expr ) return false;
    7878                assert( expr->has_result() );
    79                 return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1;
     79                return dynamic_cast< TupleType * >( expr->get_result() );
    8080        }
    8181
     
    142142                matcher->match( new_assigns );
    143143
    144                 if ( new_assigns.empty() ) return;
     144                if ( ! matcher->lhs.empty() || ! matcher->rhs.empty() ) {
     145                        // if both lhs and rhs are empty then this is the empty tuple case, wherein it's okay for new_assigns to be empty.
     146                        // if not the empty tuple case, return early so that no new alternatives are generated.
     147                        if ( new_assigns.empty() ) return;
     148                }
    145149                ResolvExpr::AltList current;
    146150                // now resolve new assignments
     
    186190
    187191                // explode the lhs so that each field of the tuple-valued-expr is assigned.
    188                 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) );
     192                explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true );
    189193
    190194                // and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed
     
    211215        TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
    212216                // explode the rhs so that each field of the tuple-valued-expr is assigned.
    213                 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs) );
     217                explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs), true );
    214218        }
    215219
     
    248252                static UniqueName lhsNamer( "__massassign_L" );
    249253                static UniqueName rhsNamer( "__massassign_R" );
    250                 assert ( ! lhs.empty() && rhs.size() <= 1);
     254                // empty tuple case falls into this matcher, hence the second part of the assert
     255                assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) );
    251256
    252257                ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr;
    253258                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     259                        // create a temporary object for each value in the lhs and create a call involving the rhs
    254260                        ObjectDecl * ltmp = newObject( lhsNamer, lhsAlt.expr );
    255261                        out.push_back( createFunc( spotter.fname, ltmp, rtmp ) );
     
    263269                static UniqueName rhsNamer( "__multassign_R" );
    264270
    265                 // xxx - need more complicated matching?
    266271                if ( lhs.size() == rhs.size() ) {
     272                        // produce a new temporary object for each value in the lhs and rhs and pairwise create the calls
    267273                        std::list< ObjectDecl * > ltmp;
    268274                        std::list< ObjectDecl * > rtmp;
  • src/Tuples/TupleExpansion.cc

    rbb82c03 r2162c2c  
    144144
    145145        Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) {
    146                 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * > ( memberExpr->get_member() ) ) {
     146                if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->get_member() ) ) {
    147147                        Expression * aggr = memberExpr->get_aggregate()->clone()->acceptMutator( *this );
    148148                        // aggregate expressions which might be impure must be wrapped in unique expressions
     
    225225                                decl->get_parameters().push_back( tyParam );
    226226                        }
     227                        if ( tupleType->size() == 0 ) {
     228                                // empty structs are not standard C. Add a dummy field to empty tuples to silence warnings when a compound literal Tuple0 is created.
     229                                decl->get_members().push_back( new ObjectDecl( "dummy", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
     230                        }
    227231                        typeMap[mangleName] = decl;
    228232                        addDeclaration( decl );
     
    315319                        qualifiers &= type->get_qualifiers();
    316320                } // for
     321                if ( exprs.empty() ) qualifiers = Type::Qualifiers();
    317322                return tupleType;
     323        }
     324
     325        TypeInstType * isTtype( Type * type ) {
     326                if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( type ) ) {
     327                        if ( inst->get_baseType()->get_kind() == TypeDecl::Ttype ) {
     328                                return inst;
     329                        }
     330                }
     331                return nullptr;
    318332        }
    319333
  • src/Tuples/Tuples.h

    rbb82c03 r2162c2c  
    4242        Type * makeTupleType( const std::list< Expression * > & exprs );
    4343
     44        /// returns a TypeInstType if `type` is a ttype, nullptr otherwise
     45        TypeInstType * isTtype( Type * type );
     46
    4447        /// returns true if the expression may contain side-effects.
    4548        bool maybeImpure( Expression * expr );
Note: See TracChangeset for help on using the changeset viewer.