Changes in / [2ff76d25:fcf3493]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cpp
r2ff76d25 rfcf3493 30 30 #include "Common/UniqueName.hpp" // for UniqueName 31 31 #include "GenPoly/FindFunction.hpp" // for findFunction 32 #include "GenPoly/GenPoly.hpp" // for getFunctionType, isPolyType,...32 #include "GenPoly/GenPoly.hpp" // for getFunctionType, ... 33 33 #include "GenPoly/Lvalue.hpp" // for generalizedLvalue 34 34 #include "GenPoly/ScopedSet.hpp" // for ScopedSet … … 670 670 } 671 671 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 679 672 bool isPolyDeref( ast::UntypedExpr const * expr, 680 673 TypeVarMap const & typeVars, 681 674 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 } 690 688 } 691 689 return false; … … 1201 1199 assert( 2 == expr->args.size() ); 1202 1200 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 ptr1207 bool isPoly1 = isPolyPtr( arg Type1, scopeTypeVars, typeSubs ) != nullptr;1208 bool isPoly2 = isPolyPtr( arg Type2, 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; 1209 1207 1210 1208 // If neither argument is a polymorphic pointer, do nothing. … … 1223 1221 new ast::NameExpr( location, "?+?" ) ); 1224 1222 if ( isPoly1 ) { 1225 auto referentType = getReferentType( argType1 ); 1223 assert( arg1Ty ); 1224 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1225 assert( arg1TyPtr ); 1226 1226 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1227 1227 expr->args.back(), 1228 new ast::SizeofExpr( location1, deepCopy( referentType ) ),1228 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ), 1229 1229 } ); 1230 1230 ret->args.push_back( expr->args.front() ); … … 1232 1232 } else { 1233 1233 assert( isPoly2 ); 1234 auto referentType = getReferentType( argType2 ); 1234 assert( arg2Ty ); 1235 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1236 assert( arg2TyPtr ); 1235 1237 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1236 1238 expr->args.front(), 1237 new ast::SizeofExpr( location2, deepCopy( referentType ) ),1239 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ), 1238 1240 } ); 1239 1241 ret->args.push_back( multiply ); … … 1248 1250 assert( 1 == expr->args.size() ); 1249 1251 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 1250 1258 // 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 ) ) { 1253 1260 return expr; 1254 1261 } … … 1315 1322 assert( 2 == expr->args.size() ); 1316 1323 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( arg Type1, scopeTypeVars, typeSubs ) != nullptr;1321 bool isPoly2 = isPolyPtr( arg Type2, 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; 1322 1329 1323 1330 CodeLocation const & location = expr->location; 1324 1331 CodeLocation const & location1 = expr->args.front()->location; 1325 1332 CodeLocation const & location2 = expr->args.back()->location; 1326 // LHS - RHS -> (LHS -RHS) / sizeof(LHS)1333 // LHS minus RHS -> (LHS minus RHS) / sizeof(LHS) 1327 1334 if ( isPoly1 && isPoly2 ) { 1328 // There are only subtraction intrinsics for this pattern.1329 1335 assert( "?-?" == varName ); 1330 auto referentType = getReferentType( argType1 ); 1336 assert( arg1Ty ); 1337 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1338 assert( arg1TyPtr ); 1331 1339 auto divide = ast::UntypedExpr::createCall( location, "?/?", { 1332 1340 expr, 1333 new ast::SizeofExpr( location, deepCopy( referentType ) ),1341 new ast::SizeofExpr( location, deepCopy( arg1TyPtr->base ) ), 1334 1342 } ); 1335 1343 if ( expr->env ) divide->env = expr->env; … … 1337 1345 // LHS op RHS -> LHS op (RHS * sizeof(LHS)) 1338 1346 } else if ( isPoly1 ) { 1339 auto referentType = getReferentType( argType1 ); 1347 assert( arg1Ty ); 1348 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1349 assert( arg1TyPtr ); 1340 1350 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1341 1351 expr->args.back(), 1342 new ast::SizeofExpr( location1, deepCopy( referentType ) ),1352 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ), 1343 1353 } ); 1344 1354 return ast::mutate_field_index( … … 1346 1356 // LHS op RHS -> (LHS * sizeof(RHS)) op RHS 1347 1357 } else if ( isPoly2 ) { 1348 auto referentType = getReferentType( argType2 ); 1358 assert( arg2Ty ); 1359 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1360 assert( arg2TyPtr ); 1349 1361 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1350 1362 expr->args.front(), 1351 new ast::SizeofExpr( location2, deepCopy( referentType ) ),1363 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ), 1352 1364 } ); 1353 1365 return ast::mutate_field_index( 1354 1366 expr, &ast::ApplicationExpr::args, 0, multiply ); 1355 1367 } 1356 // Addition and Subtra ction Relative Assignment Intrinsics:1368 // Addition and Subtration Relative Assignment Intrinsics: 1357 1369 } else if ( "?+=?" == varName || "?-=?" == varName ) { 1358 1370 assert( expr->result );
Note: See TracChangeset
for help on using the changeset viewer.