@@ -913,6 +913,9 @@ class AbstractionPattern {
913
913
bool hasCachingKey () const {
914
914
// Only the simplest Kind::Type pattern has a caching key; we
915
915
// don't want to try to unique by Clang node.
916
+ //
917
+ // Even if we support Clang nodes someday, we *cannot* cache
918
+ // by the open-coded patterns like Tuple and PackExpansion.
916
919
return getKind () == Kind::Type || getKind () == Kind::Opaque
917
920
|| getKind () == Kind::Discard;
918
921
}
@@ -1216,9 +1219,7 @@ class AbstractionPattern {
1216
1219
case Kind::Invalid:
1217
1220
llvm_unreachable (" querying invalid abstraction pattern!" );
1218
1221
case Kind::Opaque:
1219
- return typename CanTypeWrapperTraits<TYPE>::type ();
1220
1222
case Kind::Tuple:
1221
- return typename CanTypeWrapperTraits<TYPE>::type ();
1222
1223
case Kind::OpaqueFunction:
1223
1224
case Kind::OpaqueDerivativeFunction:
1224
1225
return typename CanTypeWrapperTraits<TYPE>::type ();
@@ -1275,7 +1276,7 @@ class AbstractionPattern {
1275
1276
1276
1277
// / Is the given tuple type a valid substitution of this abstraction
1277
1278
// / pattern?
1278
- bool matchesTuple (CanTupleType substType);
1279
+ bool matchesTuple (CanTupleType substType) const ;
1279
1280
1280
1281
bool isTuple () const {
1281
1282
switch (getKind ()) {
@@ -1346,6 +1347,40 @@ class AbstractionPattern {
1346
1347
return { { this , 0 }, { this , getNumTupleElements () } };
1347
1348
}
1348
1349
1350
+ // / Perform a parallel visitation of the elements of a tuple type,
1351
+ // / preserving structure about where pack expansions appear in the
1352
+ // / original type and how many elements of the substituted type they
1353
+ // / expand to.
1354
+ // /
1355
+ // / This pattern must be a tuple pattern.
1356
+ // /
1357
+ // / Calls handleScalar or handleExpansion as appropriate for each
1358
+ // / element of the original tuple, in order.
1359
+ void forEachTupleElement (CanTupleType substType,
1360
+ llvm::function_ref<void (unsigned origEltIndex,
1361
+ unsigned substEltIndex,
1362
+ AbstractionPattern origEltType,
1363
+ CanType substEltType)>
1364
+ handleScalar,
1365
+ llvm::function_ref<void(unsigned origEltIndex,
1366
+ unsigned substEltIndex,
1367
+ AbstractionPattern origExpansionType,
1368
+ CanTupleEltTypeArrayRef substEltTypes)>
1369
+ handleExpansion) const ;
1370
+
1371
+ // / Perform a parallel visitation of the elements of a tuple type,
1372
+ // / expanding the elements of the type. This preserves the structure
1373
+ // / of the *substituted* tuple type: it will be called once per element
1374
+ // / of the substituted type, in order. The original element trappings
1375
+ // / are also provided for convenience.
1376
+ // /
1377
+ // / This pattern must match the substituted type, but it may be an
1378
+ // / opaque pattern.
1379
+ void forEachExpandedTupleElement (CanTupleType substType,
1380
+ llvm::function_ref<void (AbstractionPattern origEltType,
1381
+ CanType substEltType,
1382
+ const TupleTypeElt &elt)> handleElement) const ;
1383
+
1349
1384
// / Is the given pack type a valid substitution of this abstraction
1350
1385
// / pattern?
1351
1386
bool matchesPack (CanPackType substType);
@@ -1420,13 +1455,20 @@ class AbstractionPattern {
1420
1455
// / the abstraction pattern for an element type.
1421
1456
AbstractionPattern getPackElementType (unsigned index) const ;
1422
1457
1423
- // / Give that the value being abstracted is a pack expansion type, return the
1424
- // / underlying pattern type.
1458
+ // / Given that the value being abstracted is a pack expansion type,
1459
+ // / return the underlying pattern type.
1460
+ // /
1461
+ // / If you're looking for getPackExpansionCountType(), it deliberately
1462
+ // / does not exist. Count types are not lowered types, and the original
1463
+ // / count types are not relevant to lowering. Only the substituted
1464
+ // / components and expansion counts are significant.
1425
1465
AbstractionPattern getPackExpansionPatternType () const ;
1426
1466
1427
- // / Give that the value being abstracted is a pack expansion type, return the
1428
- // / underlying count type.
1429
- AbstractionPattern getPackExpansionCountType () const ;
1467
+ // / Given that the value being abstracted is a pack expansion type,
1468
+ // / return the appropriate pattern type for the given expansion
1469
+ // / component.
1470
+ AbstractionPattern getPackExpansionComponentType (CanType substType) const ;
1471
+ AbstractionPattern getPackExpansionComponentType (bool isExpansion) const ;
1430
1472
1431
1473
// / Given that the value being abstracted is a function, return the
1432
1474
// / abstraction pattern for its result type.
@@ -1446,6 +1488,30 @@ class AbstractionPattern {
1446
1488
// / parameters in the pattern.
1447
1489
unsigned getNumFunctionParams () const ;
1448
1490
1491
+ // / Perform a parallel visitation of the parameters of a function.
1492
+ // /
1493
+ // / If this is a function pattern, calls handleScalar or
1494
+ // / handleExpansion as appropriate for each parameter of the
1495
+ // / original function, in order.
1496
+ // /
1497
+ // / If this is not a function pattern, calls handleScalar for each
1498
+ // / parameter of the substituted function type. Functions with
1499
+ // / pack expansions cannot be abstracted legally this way.
1500
+ void forEachFunctionParam (AnyFunctionType::CanParamArrayRef substParams,
1501
+ bool ignoreFinalParam,
1502
+ llvm::function_ref<void (unsigned origParamIndex,
1503
+ unsigned substParamIndex,
1504
+ ParameterTypeFlags origFlags,
1505
+ AbstractionPattern origParamType,
1506
+ AnyFunctionType::CanParam substParam)>
1507
+ handleScalar,
1508
+ llvm::function_ref<void(unsigned origParamIndex,
1509
+ unsigned substParamIndex,
1510
+ ParameterTypeFlags origFlags,
1511
+ AbstractionPattern origExpansionType,
1512
+ AnyFunctionType::CanParamArrayRef substParams)>
1513
+ handleExpansion) const ;
1514
+
1449
1515
// / Given that the value being abstracted is optional, return the
1450
1516
// / abstraction pattern for its object type.
1451
1517
AbstractionPattern getOptionalObjectType () const ;
@@ -1477,16 +1543,14 @@ class AbstractionPattern {
1477
1543
AbstractionPattern getObjCMethodAsyncCompletionHandlerType (
1478
1544
CanType swiftCompletionHandlerType) const ;
1479
1545
1480
- // / Given that this is a pack expansion, invoke the given callback for
1481
- // / each component of the substituted expansion of this pattern. The
1482
- // / pattern will be for a pack expansion type over a contextual type if
1483
- // / the substituted component is still a pack expansion. If there aren't
1484
- // / substitutions available, this will just invoke the callback with the
1485
- // / component.
1486
- void forEachPackExpandedComponent (
1487
- llvm::function_ref<void (AbstractionPattern pattern)> fn) const ;
1488
-
1489
- SmallVector<AbstractionPattern, 4 > getPackExpandedComponents () const ;
1546
+ // / Given that this is a pack expansion, return the number of components
1547
+ // / that it should expand to. This, and the general correctness of
1548
+ // / traversing variadically generic tuple and function types under
1549
+ // / substitution, relies on substitutions having been set properly
1550
+ // / on the abstraction pattern; without that, AbstractionPattern assumes
1551
+ // / that every component expands to a single pack expansion component,
1552
+ // / which will generally only work in specific situations.
1553
+ size_t getNumPackExpandedComponents () const ;
1490
1554
1491
1555
// / If this pattern refers to a foreign ObjC method that was imported as
1492
1556
// / async, return the bridged-back-to-ObjC completion handler type.
0 commit comments