Ignore:
Timestamp:
Apr 19, 2018, 6:11:07 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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, with_gc
Children:
8633f060
Parents:
9dc31c10 (diff), 60ba456 (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:

fix conflict

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    r9dc31c10 rc28afead  
    9898                };
    9999
    100                 struct AddrRef final : public WithGuards {
     100                struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting {
    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 * );
    104108
    105109                        bool first = true;
    106110                        bool current = false;
    107111                        int refDepth = 0;
     112                        bool addCast = false;
    108113                };
    109114        } // namespace
     
    208213                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    209214                                                        // 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
    210223                                                        PRINT(
    211224                                                                std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
     
    233246
    234247                // idea: &&&E: get outer &, inner &
    235                 // at inner &, record depth D of reference type
     248                // at inner &, record depth D of reference type of argument of &
    236249                // at outer &, add D derefs.
    237                 void AddrRef::premutate( Expression * ) {
     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.
    238254                        GuardValue( current );
    239255                        GuardValue( first );
     
    242258                }
    243259
     260                void AddrRef::premutate( Expression * expr ) {
     261                        handleNonAddr( expr );
     262                        GuardValue( addCast );
     263                        addCast = false;
     264                }
     265
    244266                void AddrRef::premutate( AddressExpr * ) {
    245267                        GuardValue( current );
    246268                        GuardValue( first );
    247                         current = first;
    248                         first = false;
    249                         if ( current ) {
     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
    250272                                GuardValue( refDepth );
    251                                 refDepth = 0;
     273                                refDepth = 0;  // set depth to 0 so that postmutate can find the innermost address-of easily
    252274                        }
    253275                }
    254276
    255277                Expression * AddrRef::postmutate( AddressExpr * addrExpr ) {
     278                        PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; )
    256279                        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
    257282                                if ( ! isIntrinsicReference( addrExpr->arg ) ) {
    258283                                        // 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.
    259285                                        refDepth = addrExpr->arg->result->referenceDepth();
    260                                 }
    261                         }
    262                         if ( current ) {
     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; )
    263293                                Expression * ret = addrExpr;
    264294                                while ( refDepth ) {
     295                                        // add one dereference for each
    265296                                        ret = mkDeref( ret );
    266297                                        refDepth--;
    267298                                }
     299
     300                                if ( addCast ) {
     301                                        PRINT( std::cerr << "adding cast..." << std::endl; )
     302                                        return new CastExpr( ret, addrExpr->result->clone() );
     303                                }
    268304                                return ret;
    269305                        }
     306                        PRINT( std::cerr << "not current..." << std::endl; )
    270307                        return addrExpr;
    271308                }
     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
    272327
    273328                Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) {
     
    376431                                assert( diff == 0 );
    377432                                // 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                                }
    378446                                return castExpr;
    379447                        }
Note: See TracChangeset for help on using the changeset viewer.