Changeset da7fe39 for src/GenPoly


Ignore:
Timestamp:
Apr 23, 2018, 12:57:46 PM (6 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, with_gc
Children:
57acae0
Parents:
ba89e9b7 (diff), c8ad5d9 (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 references

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rba89e9b7 rda7fe39  
    184184                        /// change the type of generic aggregate members to char[]
    185185                        void mutateMembers( AggregateDecl * aggrDecl );
     186                        /// returns the calculated sizeof expression for ty, or nullptr for use C sizeof()
     187                        Expression* genSizeof( Type* ty );
    186188
    187189                        /// Enters a new scope for type-variables, adding the type variables from ty
     
    382384                unsigned long n_members = 0;
    383385                bool firstMember = true;
    384                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    385                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
     386                for ( Declaration* member : structDecl->get_members() ) {
     387                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
    386388                        assert( dwt );
    387389                        Type *memberType = dwt->get_type();
     
    17471749                }
    17481750
     1751                Expression * PolyGenericCalculator::genSizeof( Type* ty ) {
     1752                        if ( ArrayType * aty = dynamic_cast<ArrayType *>(ty) ) {
     1753                                // generate calculated size for possibly generic array
     1754                                Expression * sizeofBase = genSizeof( aty->get_base() );
     1755                                if ( ! sizeofBase ) return nullptr;
     1756                                Expression * dim = aty->get_dimension();
     1757                                aty->set_dimension( nullptr );
     1758                                return makeOp( "?*?", sizeofBase, dim );
     1759                        } else if ( findGeneric( ty ) ) {
     1760                                // generate calculated size for generic type
     1761                                return new NameExpr( sizeofName( mangleType( ty ) ) );
     1762                        } else return nullptr;
     1763                }
     1764
    17491765                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    1750                         Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    1751                         if ( findGeneric( ty ) ) {
    1752                                 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
     1766                        Type *ty = sizeofExpr->get_isType() ?
     1767                                sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
     1768                       
     1769                        Expression * gen = genSizeof( ty );
     1770                        if ( gen ) {
    17531771                                delete sizeofExpr;
    1754                                 return ret;
    1755                         }
    1756                         return sizeofExpr;
     1772                                return gen;
     1773                        } else return sizeofExpr;
    17571774                }
    17581775
  • src/GenPoly/InstantiateGeneric.cc

    rba89e9b7 rda7fe39  
    496496        Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) {
    497497                // need to cast dtype-static member expressions to their actual type before that type is erased.
     498                // NOTE: the casts here have the third argument (isGenerated) set to false so that these casts persist until Box, where they are needed.
    498499                auto & baseParams = *inst->get_baseParameters();
    499500                if ( isDtypeStatic( baseParams ) ) {
     
    515516                                        // Note: this currently creates more temporaries than is strictly necessary, since it does not check for duplicate uses of the same member expression.
    516517                                        static UniqueName tmpNamer( "_dtype_static_member_" );
    517                                         Expression * init = new CastExpr( new AddressExpr( memberExpr ), new PointerType( Type::Qualifiers(), concType->clone() ) );
     518                                        Expression * init = new CastExpr( new AddressExpr( memberExpr ), new PointerType( Type::Qualifiers(), concType->clone() ), false );
    518519                                        ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), new ReferenceType( Type::Qualifiers(), concType ), new SingleInit( init ) );
    519520                                        stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
     
    521522                                } else {
    522523                                        // can simply add a cast to actual type
    523                                         return new CastExpr( memberExpr, concType );
     524                                        return new CastExpr( memberExpr, concType, false );
    524525                                }
    525526                        }
  • src/GenPoly/Lvalue.cc

    rba89e9b7 rda7fe39  
    9999                };
    100100
    101                 struct AddrRef final : public WithGuards {
     101                struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting {
    102102                        void premutate( AddressExpr * addrExpr );
    103103                        Expression * postmutate( AddressExpr * addrExpr );
    104104                        void premutate( Expression * expr );
     105                        void premutate( ApplicationExpr * appExpr );
     106                        void premutate( SingleInit * init );
     107
     108                        void handleNonAddr( Expression * );
    105109
    106110                        bool first = true;
    107111                        bool current = false;
    108112                        int refDepth = 0;
     113                        bool addCast = false;
    109114                };
    110115        } // namespace
     
    215220                                                )
    216221                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    217                                                 // if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    218                                                 //      // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
    219                                                 //      // PRINT(
    220                                                 //              std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
    221                                                 //      // )
    222                                                 //      arg = new AddressExpr( arg );
    223                                                 // } else
    224                                                 // if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    225                                                 if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    226 
     222
     223                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    227224                                                        // needed for definition of prelude functions, etc.
    228 
     225                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
     226
     227                                                        // NOTE: previously, this condition fixed
     228                                                        //   void f(int *&);
     229                                                        //   int & x = ...;
     230                                                        //   f(&x);
     231                                                        // But now this is taken care of by a reference cast added by AddrRef. Need to find a new
     232                                                        // example or remove this branch.
     233
     234                                                        PRINT(
     235                                                                std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
     236                                                        )
     237                                                        arg = new AddressExpr( arg );
     238                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
     239                                                } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    229240                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
    230241                                                        PRINT(
     
    247258
    248259                // idea: &&&E: get outer &, inner &
    249                 // at inner &, record depth D of reference type
     260                // at inner &, record depth D of reference type of argument of &
    250261                // at outer &, add D derefs.
    251                 void AddrRef::premutate( Expression * ) {
     262                void AddrRef::handleNonAddr( Expression * ) {
     263                        // non-address-of: reset status variables:
     264                        // * current expr is NOT the first address-of expr in an address-of chain
     265                        // * next seen address-of expr IS the first in the chain.
    252266                        GuardValue( current );
    253267                        GuardValue( first );
     
    256270                }
    257271
     272                void AddrRef::premutate( Expression * expr ) {
     273                        handleNonAddr( expr );
     274                        GuardValue( addCast );
     275                        addCast = false;
     276                }
     277
    258278                void AddrRef::premutate( AddressExpr * ) {
    259279                        GuardValue( current );
    260280                        GuardValue( first );
    261                         current = first;
    262                         first = false;
    263                         if ( current ) {
     281                        current = first; // is this the first address-of in the chain?
     282                        first = false;   // from here out, no longer possible for next address-of to be first in chain
     283                        if ( current ) { // this is the outermost address-of in a chain
    264284                                GuardValue( refDepth );
    265                                 refDepth = 0;
     285                                refDepth = 0;  // set depth to 0 so that postmutate can find the innermost address-of easily
    266286                        }
    267287                }
    268288
    269289                Expression * AddrRef::postmutate( AddressExpr * addrExpr ) {
     290                        PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; )
    270291                        if ( refDepth == 0 ) {
     292                                PRINT( std::cerr << "depth 0, get new depth..." << std::endl; )
     293                                // this is the innermost address-of in a chain, record depth D
    271294                                if ( ! isIntrinsicReference( addrExpr->arg ) ) {
    272295                                        // try to avoid ?[?]
     296                                        // 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.
    273297                                        refDepth = addrExpr->arg->result->referenceDepth();
    274                                 }
    275                         }
    276                         if ( current ) {
     298                                        PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; )
     299                                } else {
     300                                        assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) );
     301                                }
     302                        }
     303                        if ( current ) { // this is the outermost address-of in a chain
     304                                PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; )
    277305                                Expression * ret = addrExpr;
    278306                                while ( refDepth ) {
     307                                        // add one dereference for each
    279308                                        ret = mkDeref( ret );
    280309                                        refDepth--;
    281310                                }
     311
     312                                if ( addCast ) {
     313                                        PRINT( std::cerr << "adding cast..." << std::endl; )
     314                                        return new CastExpr( ret, addrExpr->result->clone() );
     315                                }
    282316                                return ret;
    283317                        }
     318                        PRINT( std::cerr << "not current..." << std::endl; )
    284319                        return addrExpr;
    285320                }
     321
     322                void AddrRef::premutate( ApplicationExpr * appExpr ) {
     323                        visit_children = false;
     324                        GuardValue( addCast );
     325                        handleNonAddr( appExpr );
     326                        for ( Expression *& arg : appExpr->args ) {
     327                                // each argument with address-of requires a cast
     328                                addCast = true;
     329                                arg = arg->acceptMutator( *visitor );
     330                        }
     331                }
     332
     333                void AddrRef::premutate( SingleInit * ) {
     334                        GuardValue( addCast );
     335                        // each initialization context with address-of requires a cast
     336                        addCast = true;
     337                }
     338
    286339
    287340                Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) {
     
    391444                                assert( diff == 0 );
    392445                                // conversion between references of the same depth
     446                                if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) {
     447                                        // Remove useless generated casts
     448                                        PRINT(
     449                                                std::cerr << "types are compatible, removing cast: " << castExpr << std::endl;
     450                                                std::cerr << "-- " << castExpr->result << std::endl;
     451                                                std::cerr << "-- " << castExpr->arg->result << std::endl;
     452                                        )
     453                                        Expression * ret = castExpr->arg;
     454                                        castExpr->arg = nullptr;
     455                                        std::swap( castExpr->env, ret->env );
     456                                        delete castExpr;
     457                                        return ret;
     458                                }
    393459                                return castExpr;
    394460                        }
Note: See TracChangeset for help on using the changeset viewer.