Changeset 82d5816
- Timestamp:
- Jul 30, 2024, 12:11:55 PM (4 months ago)
- Branches:
- master
- Children:
- 2ff76d25
- Parents:
- dd78dbc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cpp
rdd78dbc r82d5816 30 30 #include "Common/UniqueName.hpp" // for UniqueName 31 31 #include "GenPoly/FindFunction.hpp" // for findFunction 32 #include "GenPoly/GenPoly.hpp" // for getFunctionType, ...32 #include "GenPoly/GenPoly.hpp" // for getFunctionType, isPolyType, ... 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 672 679 bool isPolyDeref( ast::UntypedExpr const * expr, 673 680 TypeVarMap const & typeVars, 674 681 ast::TypeSubstitution const * 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 } 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 ); 688 690 } 689 691 return false; … … 1199 1201 assert( 2 == expr->args.size() ); 1200 1202 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 ptr1205 bool isPoly1 = isPolyPtr( arg 1Ty, scopeTypeVars, typeSubs ) != nullptr;1206 bool isPoly2 = isPolyPtr( arg 2Ty, scopeTypeVars, typeSubs ) != nullptr;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; 1207 1209 1208 1210 // If neither argument is a polymorphic pointer, do nothing. … … 1221 1223 new ast::NameExpr( location, "?+?" ) ); 1222 1224 if ( isPoly1 ) { 1223 assert( arg1Ty ); 1224 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1225 assert( arg1TyPtr ); 1225 auto referentType = getReferentType( argType1 ); 1226 1226 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1227 1227 expr->args.back(), 1228 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),1228 new ast::SizeofExpr( location1, deepCopy( referentType ) ), 1229 1229 } ); 1230 1230 ret->args.push_back( expr->args.front() ); … … 1232 1232 } else { 1233 1233 assert( isPoly2 ); 1234 assert( arg2Ty ); 1235 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1236 assert( arg2TyPtr ); 1234 auto referentType = getReferentType( argType2 ); 1237 1235 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1238 1236 expr->args.front(), 1239 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),1237 new ast::SizeofExpr( location2, deepCopy( referentType ) ), 1240 1238 } ); 1241 1239 ret->args.push_back( multiply ); … … 1250 1248 assert( 1 == expr->args.size() ); 1251 1249 1252 auto ptrExpr = expr->args.front();1253 auto ptrTy = ptrExpr->result.as<ast::PointerType>();1254 assert(ptrTy); // thing being deref'd must be pointer1255 auto referentTy = ptrTy->base;1256 assert(referentTy);1257 1258 1250 // If this isn't for a poly type, then do nothing. 1259 if ( !isPolyType( referentTy, scopeTypeVars, typeSubs ) ) { 1251 auto referentType = getReferentType( expr->args.front()->result ); 1252 if ( !isPolyType( referentType, scopeTypeVars, typeSubs ) ) { 1260 1253 return expr; 1261 1254 } … … 1322 1315 assert( 2 == expr->args.size() ); 1323 1316 1324 ast:: Type const * arg1Ty= expr->args.front()->result;1325 ast:: Type const * arg2Ty= expr->args.back()->result;1326 1327 bool isPoly1 = isPolyPtr( arg 1Ty, scopeTypeVars, typeSubs ) != nullptr;1328 bool isPoly2 = isPolyPtr( arg 2Ty, scopeTypeVars, typeSubs ) != nullptr;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; 1329 1322 1330 1323 CodeLocation const & location = expr->location; 1331 1324 CodeLocation const & location1 = expr->args.front()->location; 1332 1325 CodeLocation const & location2 = expr->args.back()->location; 1333 // LHS minus RHS -> (LHS minusRHS) / sizeof(LHS)1326 // LHS - RHS -> (LHS - RHS) / sizeof(LHS) 1334 1327 if ( isPoly1 && isPoly2 ) { 1328 // There are only subtraction intrinsics for this pattern. 1335 1329 assert( "?-?" == varName ); 1336 assert( arg1Ty ); 1337 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1338 assert( arg1TyPtr ); 1330 auto referentType = getReferentType( argType1 ); 1339 1331 auto divide = ast::UntypedExpr::createCall( location, "?/?", { 1340 1332 expr, 1341 new ast::SizeofExpr( location, deepCopy( arg1TyPtr->base ) ),1333 new ast::SizeofExpr( location, deepCopy( referentType ) ), 1342 1334 } ); 1343 1335 if ( expr->env ) divide->env = expr->env; … … 1345 1337 // LHS op RHS -> LHS op (RHS * sizeof(LHS)) 1346 1338 } else if ( isPoly1 ) { 1347 assert( arg1Ty ); 1348 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1349 assert( arg1TyPtr ); 1339 auto referentType = getReferentType( argType1 ); 1350 1340 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1351 1341 expr->args.back(), 1352 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),1342 new ast::SizeofExpr( location1, deepCopy( referentType ) ), 1353 1343 } ); 1354 1344 return ast::mutate_field_index( … … 1356 1346 // LHS op RHS -> (LHS * sizeof(RHS)) op RHS 1357 1347 } else if ( isPoly2 ) { 1358 assert( arg2Ty ); 1359 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1360 assert( arg2TyPtr ); 1348 auto referentType = getReferentType( argType2 ); 1361 1349 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1362 1350 expr->args.front(), 1363 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),1351 new ast::SizeofExpr( location2, deepCopy( referentType ) ), 1364 1352 } ); 1365 1353 return ast::mutate_field_index( 1366 1354 expr, &ast::ApplicationExpr::args, 0, multiply ); 1367 1355 } 1368 // Addition and Subtra tion Relative Assignment Intrinsics:1356 // Addition and Subtraction Relative Assignment Intrinsics: 1369 1357 } else if ( "?+=?" == varName || "?-=?" == varName ) { 1370 1358 assert( expr->result );
Note: See TracChangeset
for help on using the changeset viewer.