Changes in src/GenPoly/Box.cpp [fd4df379:c92bdcc]
- File:
-
- 1 edited
-
src/GenPoly/Box.cpp (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cpp
rfd4df379 rc92bdcc 673 673 TypeVarMap const & typeVars, 674 674 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 ); 675 if ( expr->result && isPolyType( expr->result, typeVars, typeSubs ) ) { 676 if ( auto name = expr->func.as<ast::NameExpr>() ) { 677 if ( "*?" == name->name ) { 678 return true; 679 } 687 680 } 688 681 } … … 1199 1192 assert( 2 == expr->args.size() ); 1200 1193 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; 1207 1194 ast::Type const * baseType1 = 1195 isPolyPtr( expr->args.front()->result, scopeTypeVars, typeSubs ); 1196 ast::Type const * baseType2 = 1197 isPolyPtr( expr->args.back()->result, scopeTypeVars, typeSubs ); 1208 1198 // If neither argument is a polymorphic pointer, do nothing. 1209 if ( ! isPoly1 && !isPoly2 ) {1199 if ( !baseType1 && !baseType2 ) { 1210 1200 return expr; 1211 1201 } 1212 1202 // The arguments cannot both be polymorphic pointers. 1213 assert( ! isPoly1 || !isPoly2 );1203 assert( !baseType1 || !baseType2 ); 1214 1204 // (So exactly one of the arguments is a polymorphic pointer.) 1215 1205 … … 1220 1210 ast::UntypedExpr * ret = new ast::UntypedExpr( location, 1221 1211 new ast::NameExpr( location, "?+?" ) ); 1222 if ( isPoly1 ) { 1223 assert( arg1Ty ); 1224 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1225 assert( arg1TyPtr ); 1212 if ( baseType1 ) { 1226 1213 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1227 1214 expr->args.back(), 1228 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base) ),1215 new ast::SizeofExpr( location1, deepCopy( baseType1 ) ), 1229 1216 } ); 1230 1217 ret->args.push_back( expr->args.front() ); 1231 1218 ret->args.push_back( multiply ); 1232 1219 } else { 1233 assert( isPoly2 ); 1234 assert( arg2Ty ); 1235 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1236 assert( arg2TyPtr ); 1220 assert( baseType2 ); 1237 1221 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1238 1222 expr->args.front(), 1239 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base) ),1223 new ast::SizeofExpr( location2, deepCopy( baseType2 ) ), 1240 1224 } ); 1241 1225 ret->args.push_back( multiply ); … … 1250 1234 assert( 1 == expr->args.size() ); 1251 1235 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 1236 // If this isn't for a poly type, then do nothing. 1259 if ( !isPolyType( referentTy, scopeTypeVars, typeSubs ) ) {1237 if ( !isPolyType( expr->result, scopeTypeVars, typeSubs ) ) { 1260 1238 return expr; 1261 1239 } … … 1265 1243 // Fix expression type to remove pointer. 1266 1244 ret->result = expr->result; 1267 // apply pointer decay1268 if (auto retArTy = ret->result.as<ast::ArrayType>()) {1269 ret->result = new ast::PointerType( retArTy->base );1270 }1271 1245 ret->env = expr->env ? expr->env : ret->env; 1272 1246 return ret; … … 1317 1291 return makeIncrDecrExpr( 1318 1292 expr->location, expr, baseType, "++?" == varName ); 1319 // Addition and Subtra ction Intrinsics:1293 // Addition and Subtration Intrinsics: 1320 1294 } else if ( "?+?" == varName || "?-?" == varName ) { 1321 1295 assert( expr->result ); 1322 1296 assert( 2 == expr->args.size() ); 1323 1297 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; 1298 auto baseType1 = 1299 isPolyPtr( expr->args.front()->result, scopeTypeVars, typeSubs ); 1300 auto baseType2 = 1301 isPolyPtr( expr->args.back()->result, scopeTypeVars, typeSubs ); 1329 1302 1330 1303 CodeLocation const & location = expr->location; 1331 1304 CodeLocation const & location1 = expr->args.front()->location; 1332 1305 CodeLocation const & location2 = expr->args.back()->location; 1333 // LHS minus RHS -> (LHS minus RHS) / sizeof(LHS) 1334 if ( isPoly1 && isPoly2 ) { 1335 assert( "?-?" == varName ); 1336 assert( arg1Ty ); 1337 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1338 assert( arg1TyPtr ); 1306 // LHS op RHS -> (LHS op RHS) / sizeof(LHS) 1307 if ( baseType1 && baseType2 ) { 1339 1308 auto divide = ast::UntypedExpr::createCall( location, "?/?", { 1340 1309 expr, 1341 new ast::SizeofExpr( location, deepCopy( arg1TyPtr->base) ),1310 new ast::SizeofExpr( location, deepCopy( baseType1 ) ), 1342 1311 } ); 1343 1312 if ( expr->env ) divide->env = expr->env; 1344 1313 return divide; 1345 1314 // LHS op RHS -> LHS op (RHS * sizeof(LHS)) 1346 } else if ( isPoly1 ) { 1347 assert( arg1Ty ); 1348 auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty ); 1349 assert( arg1TyPtr ); 1315 } else if ( baseType1 ) { 1350 1316 auto multiply = ast::UntypedExpr::createCall( location2, "?*?", { 1351 1317 expr->args.back(), 1352 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base) ),1318 new ast::SizeofExpr( location1, deepCopy( baseType1 ) ), 1353 1319 } ); 1354 1320 return ast::mutate_field_index( 1355 1321 expr, &ast::ApplicationExpr::args, 1, multiply ); 1356 1322 // LHS op RHS -> (LHS * sizeof(RHS)) op RHS 1357 } else if ( isPoly2 ) { 1358 assert( arg2Ty ); 1359 auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty ); 1360 assert( arg2TyPtr ); 1323 } else if ( baseType2 ) { 1361 1324 auto multiply = ast::UntypedExpr::createCall( location1, "?*?", { 1362 1325 expr->args.front(), 1363 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base) ),1326 new ast::SizeofExpr( location2, deepCopy( baseType2 ) ), 1364 1327 } ); 1365 1328 return ast::mutate_field_index( … … 1625 1588 /// Change the type of generic aggregate members to char[]. 1626 1589 void mutateMembers( ast::AggregateDecl * aggr ); 1627 /// Returns the calculated sizeof /alignof expressions for type, or1628 /// nullptr for use C size/alignof().1590 /// Returns the calculated sizeof expression for type, or nullptr for use 1591 /// C sizeof(). 1629 1592 ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * ); 1630 ast::Expr const * genAlignof( CodeLocation const &, ast::Type const * );1631 1593 /// Enters a new scope for type-variables, 1632 1594 /// adding the type variables from the provided type. … … 1651 1613 {} 1652 1614 1653 static ast::Type * polyToMonoTypeRec( CodeLocation const & loc,1654 ast::Type const * ty ) {1655 ast::Type * ret;1656 if ( auto aTy = dynamic_cast<ast::ArrayType const *>( ty ) ) {1657 // recursive case1658 auto monoBase = polyToMonoTypeRec( loc, aTy->base );1659 ret = new ast::ArrayType( monoBase, aTy->dimension,1660 aTy->isVarLen, aTy->isStatic, aTy->qualifiers );1661 } else {1662 // base case1663 auto charType = new ast::BasicType( ast::BasicKind::Char );1664 auto size = new ast::NameExpr( loc,1665 sizeofName( Mangle::mangleType( ty ) ) );1666 ret = new ast::ArrayType( charType, size,1667 ast::VariableLen, ast::DynamicDim, ast::CV::Qualifiers() );1668 }1669 return ret;1670 }1671 1672 1615 /// Converts polymorphic type into a suitable monomorphic representation. 1673 /// Simple cases: T -> __attribute__(( aligned(8) )) char[sizeof_T]; 1674 /// Array cases: T[eOut][eIn] -> __attribute__(( aligned(8) )) char[eOut][eIn][sizeof_T]; 1675 ast::Type * polyToMonoType( CodeLocation const & loc, ast::Type const * ty ) { 1676 auto ret = polyToMonoTypeRec( loc, ty ); 1616 /// Currently: __attribute__(( aligned(8) )) char[size_T]; 1617 ast::Type * polyToMonoType( CodeLocation const & location, 1618 ast::Type const * declType ) { 1619 auto charType = new ast::BasicType( ast::BasicKind::Char ); 1620 auto size = new ast::NameExpr( location, 1621 sizeofName( Mangle::mangleType( declType ) ) ); 1622 auto ret = new ast::ArrayType( charType, size, 1623 ast::VariableLen, ast::DynamicDim, ast::CV::Qualifiers() ); 1677 1624 ret->attributes.emplace_back( new ast::Attribute( "aligned", 1678 { ast::ConstantExpr::from_int( loc , 8 ) } ) );1625 { ast::ConstantExpr::from_int( location, 8 ) } ) ); 1679 1626 return ret; 1680 1627 } … … 1769 1716 // Forally, side effects are not safe in this function. But it works. 1770 1717 erase_if( mutDecl->attributes, matchAndMove ); 1771 1772 // Change the decl's type.1773 // Upon finishing the box pass, it shall be void*.1774 // At this middle-of-box-pass point, that type is T.1775 1776 // example 11777 // before box: T t ;1778 // before here: char _bufxx [_sizeof_Y1T]; T t = _bufxx;1779 // after here: char _bufxx [_sizeof_Y1T]; T t = _bufxx; (no change here - non array case)1780 // after box: char _bufxx [_sizeof_Y1T]; void *t = _bufxx;1781 1782 // example 21783 // before box: T t[42] ;1784 // before here: char _bufxx[42][_sizeof_Y1T]; T t[42] = _bufxx;1785 // after here: char _bufxx[42][_sizeof_Y1T]; T t = _bufxx;1786 // after box: char _bufxx[42][_sizeof_Y1T]; void *t = _bufxx;1787 1788 // Strip all "array of" wrappers1789 while ( auto arrayType = dynamic_cast<ast::ArrayType const *>( mutDecl->type.get() ) ) {1790 mutDecl->type = arrayType->base;1791 }1792 1718 1793 1719 mutDecl->init = new ast::SingleInit( decl->location, … … 1943 1869 ast::AlignofExpr const * expr ) { 1944 1870 ast::Type const * type = expr->type ? expr->type : expr->expr->result; 1945 ast::Expr const * gen = genAlignof( expr->location, type ); 1946 return ( gen ) ? gen : expr; 1871 if ( findGeneric( expr->location, type ) ) { 1872 return new ast::NameExpr( expr->location, 1873 alignofName( Mangle::mangleType( type ) ) ); 1874 } else { 1875 return expr; 1876 } 1947 1877 } 1948 1878 … … 2165 2095 2166 2096 return true; 2167 2168 } else if ( auto inst = dynamic_cast<ast::ArrayType const *>( type ) ) {2169 return findGeneric( location, inst->base );2170 2097 } 2171 2098 return false; … … 2228 2155 return makeOp( location, "?*?", sizeofBase, dim ); 2229 2156 } else if ( findGeneric( location, type ) ) { 2230 // Generate reference to _sizeof parameter2157 // Generate calculated size for generic type. 2231 2158 return new ast::NameExpr( location, sizeofName( 2232 Mangle::mangleType( type ) ) );2233 } else {2234 return nullptr;2235 }2236 }2237 2238 ast::Expr const * PolyGenericCalculator::genAlignof(2239 CodeLocation const & location, ast::Type const * type ) {2240 if ( auto * array = dynamic_cast<ast::ArrayType const *>( type ) ) {2241 // alignof array is alignof element2242 return genAlignof( location, array->base );2243 } else if ( findGeneric( location, type ) ) {2244 // Generate reference to _alignof parameter2245 return new ast::NameExpr( location, alignofName(2246 2159 Mangle::mangleType( type ) ) ); 2247 2160 } else {
Note:
See TracChangeset
for help on using the changeset viewer.