Changes in / [2ff76d25:fcf3493]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cpp

    r2ff76d25 rfcf3493  
    3030#include "Common/UniqueName.hpp"       // for UniqueName
    3131#include "GenPoly/FindFunction.hpp"    // for findFunction
    32 #include "GenPoly/GenPoly.hpp"         // for getFunctionType, isPolyType, ...
     32#include "GenPoly/GenPoly.hpp"         // for getFunctionType, ...
    3333#include "GenPoly/Lvalue.hpp"          // for generalizedLvalue
    3434#include "GenPoly/ScopedSet.hpp"       // for ScopedSet
     
    670670}
    671671
    672 // Get the referent (base type of pointer). Must succeed.
    673 ast::Type const * getReferentType( ast::ptr<ast::Type> const & type ) {
    674         auto pointerType = type.strict_as<ast::PointerType>();
    675         assertf( pointerType->base, "getReferentType: pointer base is nullptr." );
    676         return pointerType->base.get();
    677 }
    678 
    679672bool isPolyDeref( ast::UntypedExpr const * expr,
    680673                TypeVarMap const & typeVars,
    681674                ast::TypeSubstitution const * typeSubs ) {
    682         auto name = expr->func.as<ast::NameExpr>();
    683         if ( name && "*?" == name->name ) {
    684                 // It's a deref.
    685                 // Must look under the * (and strip its ptr-ty) because expr's
    686                 // result could be ar/ptr-decayed.  If expr.inner:T(*)[n], then
    687                 // expr is a poly deref, even though expr:T*, which is not poly.
    688                 auto referentType = getReferentType( expr->args.front()->result );
    689                 return isPolyType( referentType, typeVars, typeSubs );
     675        if ( auto name = expr->func.as<ast::NameExpr>() ) {
     676                if ( "*?" == name->name ) {
     677                        // It's a deref.
     678                        // Must look under the * (and strip its ptr-ty) because expr's
     679                        // result could be ar/ptr-decayed.  If expr.inner:T(*)[n], then
     680                        // expr is a poly deref, even though expr:T*, which is not poly.
     681                        auto ptrExpr = expr->args.front();
     682                        auto ptrTy = ptrExpr->result.as<ast::PointerType>();
     683                        assert(ptrTy); // thing being deref'd must be pointer
     684                        auto referentTy = ptrTy->base;
     685                        assert(referentTy);
     686                        return isPolyType( referentTy, typeVars, typeSubs );
     687                }
    690688        }
    691689        return false;
     
    12011199                assert( 2 == expr->args.size() );
    12021200
    1203                 ast::ptr<ast::Type> const & argType1 = expr->args.front()->result;
    1204                 ast::ptr<ast::Type> const & argType2 = expr->args.back()->result;
    1205 
    1206                 // Two Cases: a[i] with first arg poly ptr, i[a] with second arg poly ptr
    1207                 bool isPoly1 = isPolyPtr( argType1, scopeTypeVars, typeSubs ) != nullptr;
    1208                 bool isPoly2 = isPolyPtr( argType2, scopeTypeVars, typeSubs ) != nullptr;
     1201                ast::Type const * arg1Ty = expr->args.front()->result;
     1202                ast::Type const * arg2Ty = expr->args.back()->result;
     1203
     1204                // two cases: a[i] with first arg poly ptr, i[a] with second arg poly ptr
     1205                bool isPoly1 = isPolyPtr( arg1Ty, scopeTypeVars, typeSubs ) != nullptr;
     1206                bool isPoly2 = isPolyPtr( arg2Ty, scopeTypeVars, typeSubs ) != nullptr;
    12091207
    12101208                // If neither argument is a polymorphic pointer, do nothing.
     
    12231221                                new ast::NameExpr( location, "?+?" ) );
    12241222                if ( isPoly1 ) {
    1225                         auto referentType = getReferentType( argType1 );
     1223                        assert( arg1Ty );
     1224                        auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
     1225                        assert( arg1TyPtr );
    12261226                        auto multiply = ast::UntypedExpr::createCall( location2, "?*?", {
    12271227                                expr->args.back(),
    1228                                 new ast::SizeofExpr( location1, deepCopy( referentType ) ),
     1228                                new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),
    12291229                        } );
    12301230                        ret->args.push_back( expr->args.front() );
     
    12321232                } else {
    12331233                        assert( isPoly2 );
    1234                         auto referentType = getReferentType( argType2 );
     1234                        assert( arg2Ty );
     1235                        auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty );
     1236                        assert( arg2TyPtr );
    12351237                        auto multiply = ast::UntypedExpr::createCall( location1, "?*?", {
    12361238                                expr->args.front(),
    1237                                 new ast::SizeofExpr( location2, deepCopy( referentType ) ),
     1239                                new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),
    12381240                        } );
    12391241                        ret->args.push_back( multiply );
     
    12481250                assert( 1 == expr->args.size() );
    12491251
     1252                auto ptrExpr = expr->args.front();
     1253                auto ptrTy = ptrExpr->result.as<ast::PointerType>();
     1254                assert(ptrTy); // thing being deref'd must be pointer
     1255                auto referentTy = ptrTy->base;
     1256                assert(referentTy);
     1257
    12501258                // If this isn't for a poly type, then do nothing.
    1251                 auto referentType = getReferentType( expr->args.front()->result );
    1252                 if ( !isPolyType( referentType, scopeTypeVars, typeSubs ) ) {
     1259                if ( !isPolyType( referentTy, scopeTypeVars, typeSubs ) ) {
    12531260                        return expr;
    12541261                }
     
    13151322                assert( 2 == expr->args.size() );
    13161323
    1317                 ast::ptr<ast::Type> const & argType1 = expr->args.front()->result;
    1318                 ast::ptr<ast::Type> const & argType2 = expr->args.back()->result;
    1319 
    1320                 bool isPoly1 = isPolyPtr( argType1, scopeTypeVars, typeSubs ) != nullptr;
    1321                 bool isPoly2 = isPolyPtr( argType2, scopeTypeVars, typeSubs ) != nullptr;
     1324                ast::Type const * arg1Ty = expr->args.front()->result;
     1325                ast::Type const * arg2Ty = expr->args.back()->result;
     1326
     1327                bool isPoly1 = isPolyPtr( arg1Ty, scopeTypeVars, typeSubs ) != nullptr;
     1328                bool isPoly2 = isPolyPtr( arg2Ty, scopeTypeVars, typeSubs ) != nullptr;
    13221329
    13231330                CodeLocation const & location = expr->location;
    13241331                CodeLocation const & location1 = expr->args.front()->location;
    13251332                CodeLocation const & location2 = expr->args.back()->location;
    1326                 // LHS - RHS -> (LHS - RHS) / sizeof(LHS)
     1333                // LHS minus RHS -> (LHS minus RHS) / sizeof(LHS)
    13271334                if ( isPoly1 && isPoly2 ) {
    1328                         // There are only subtraction intrinsics for this pattern.
    13291335                        assert( "?-?" == varName );
    1330                         auto referentType = getReferentType( argType1 );
     1336                        assert( arg1Ty );
     1337                        auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
     1338                        assert( arg1TyPtr );
    13311339                        auto divide = ast::UntypedExpr::createCall( location, "?/?", {
    13321340                                expr,
    1333                                 new ast::SizeofExpr( location, deepCopy( referentType ) ),
     1341                                new ast::SizeofExpr( location, deepCopy( arg1TyPtr->base ) ),
    13341342                        } );
    13351343                        if ( expr->env ) divide->env = expr->env;
     
    13371345                // LHS op RHS -> LHS op (RHS * sizeof(LHS))
    13381346                } else if ( isPoly1 ) {
    1339                         auto referentType = getReferentType( argType1 );
     1347                        assert( arg1Ty );
     1348                        auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
     1349                        assert( arg1TyPtr );
    13401350                        auto multiply = ast::UntypedExpr::createCall( location2, "?*?", {
    13411351                                expr->args.back(),
    1342                                 new ast::SizeofExpr( location1, deepCopy( referentType ) ),
     1352                                new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),
    13431353                        } );
    13441354                        return ast::mutate_field_index(
     
    13461356                // LHS op RHS -> (LHS * sizeof(RHS)) op RHS
    13471357                } else if ( isPoly2 ) {
    1348                         auto referentType = getReferentType( argType2 );
     1358                        assert( arg2Ty );
     1359                        auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty );
     1360                        assert( arg2TyPtr );
    13491361                        auto multiply = ast::UntypedExpr::createCall( location1, "?*?", {
    13501362                                expr->args.front(),
    1351                                 new ast::SizeofExpr( location2, deepCopy( referentType ) ),
     1363                                new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),
    13521364                        } );
    13531365                        return ast::mutate_field_index(
    13541366                                expr, &ast::ApplicationExpr::args, 0, multiply );
    13551367                }
    1356         // Addition and Subtraction Relative Assignment Intrinsics:
     1368        // Addition and Subtration Relative Assignment Intrinsics:
    13571369        } else if ( "?+=?" == varName || "?-=?" == varName ) {
    13581370                assert( expr->result );
Note: See TracChangeset for help on using the changeset viewer.