Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    rf74eb47 ra9b1b0c  
    9898                };
    9999
    100                 struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting {
     100                struct AddrRef final : public WithGuards {
    101101                        void premutate( AddressExpr * addrExpr );
    102102                        Expression * postmutate( AddressExpr * addrExpr );
    103103                        void premutate( Expression * expr );
    104                         void premutate( ApplicationExpr * appExpr );
    105                         void premutate( SingleInit * init );
    106 
    107                         void handleNonAddr( Expression * );
    108104
    109105                        bool first = true;
    110106                        bool current = false;
    111107                        int refDepth = 0;
    112                         bool addCast = false;
    113108                };
    114109        } // namespace
     
    213208                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    214209                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
    215 
    216                                                         // NOTE: previously, this condition fixed
    217                                                         //   void f(int *&);
    218                                                         //   int & x = ...;
    219                                                         //   f(&x);
    220                                                         // But now this is taken care of by a reference cast added by AddrRef. Need to find a new
    221                                                         // example or remove this branch.
    222 
    223210                                                        PRINT(
    224211                                                                std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
     
    246233
    247234                // idea: &&&E: get outer &, inner &
    248                 // at inner &, record depth D of reference type of argument of &
     235                // at inner &, record depth D of reference type
    249236                // at outer &, add D derefs.
    250                 void AddrRef::handleNonAddr( Expression * ) {
    251                         // non-address-of: reset status variables:
    252                         // * current expr is NOT the first address-of expr in an address-of chain
    253                         // * next seen address-of expr IS the first in the chain.
     237                void AddrRef::premutate( Expression * ) {
    254238                        GuardValue( current );
    255239                        GuardValue( first );
     
    258242                }
    259243
    260                 void AddrRef::premutate( Expression * expr ) {
    261                         handleNonAddr( expr );
    262                         GuardValue( addCast );
    263                         addCast = false;
    264                 }
    265 
    266244                void AddrRef::premutate( AddressExpr * ) {
    267245                        GuardValue( current );
    268246                        GuardValue( first );
    269                         current = first; // is this the first address-of in the chain?
    270                         first = false;   // from here out, no longer possible for next address-of to be first in chain
    271                         if ( current ) { // this is the outermost address-of in a chain
     247                        current = first;
     248                        first = false;
     249                        if ( current ) {
    272250                                GuardValue( refDepth );
    273                                 refDepth = 0;  // set depth to 0 so that postmutate can find the innermost address-of easily
     251                                refDepth = 0;
    274252                        }
    275253                }
    276254
    277255                Expression * AddrRef::postmutate( AddressExpr * addrExpr ) {
    278                         PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; )
    279256                        if ( refDepth == 0 ) {
    280                                 PRINT( std::cerr << "depth 0, get new depth..." << std::endl; )
    281                                 // this is the innermost address-of in a chain, record depth D
    282257                                if ( ! isIntrinsicReference( addrExpr->arg ) ) {
    283258                                        // try to avoid ?[?]
    284                                         // xxx - is this condition still necessary? intrinsicReferences should have a cast around them at this point, so I don't think this condition ever fires.
    285259                                        refDepth = addrExpr->arg->result->referenceDepth();
    286                                         PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; )
    287                                 } else {
    288                                         assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) );
    289                                 }
    290                         }
    291                         if ( current ) { // this is the outermost address-of in a chain
    292                                 PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; )
     260                                }
     261                        }
     262                        if ( current ) {
    293263                                Expression * ret = addrExpr;
    294264                                while ( refDepth ) {
    295                                         // add one dereference for each
    296265                                        ret = mkDeref( ret );
    297266                                        refDepth--;
    298267                                }
    299 
    300                                 if ( addCast ) {
    301                                         PRINT( std::cerr << "adding cast..." << std::endl; )
    302                                         return new CastExpr( ret, addrExpr->result->clone() );
    303                                 }
    304                                 return ret;
    305                         }
    306                         PRINT( std::cerr << "not current..." << std::endl; )
     268                                return ret;
     269                        }
    307270                        return addrExpr;
    308271                }
    309 
    310                 void AddrRef::premutate( ApplicationExpr * appExpr ) {
    311                         visit_children = false;
    312                         GuardValue( addCast );
    313                         handleNonAddr( appExpr );
    314                         for ( Expression *& arg : appExpr->args ) {
    315                                 // each argument with address-of requires a cast
    316                                 addCast = true;
    317                                 arg = arg->acceptMutator( *visitor );
    318                         }
    319                 }
    320 
    321                 void AddrRef::premutate( SingleInit * ) {
    322                         GuardValue( addCast );
    323                         // each initialization context with address-of requires a cast
    324                         addCast = true;
    325                 }
    326 
    327272
    328273                Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) {
     
    431376                                assert( diff == 0 );
    432377                                // conversion between references of the same depth
    433                                 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) {
    434                                         // Remove useless generated casts
    435                                         PRINT(
    436                                                 std::cerr << "types are compatible, removing cast: " << castExpr << std::endl;
    437                                                 std::cerr << "-- " << castExpr->result << std::endl;
    438                                                 std::cerr << "-- " << castExpr->arg->result << std::endl;
    439                                         )
    440                                         Expression * ret = castExpr->arg;
    441                                         castExpr->arg = nullptr;
    442                                         std::swap( castExpr->env, ret->env );
    443                                         delete castExpr;
    444                                         return ret;
    445                                 }
    446378                                return castExpr;
    447379                        }
Note: See TracChangeset for help on using the changeset viewer.