@@ -407,10 +407,10 @@ class alignas(1 << TypeAlignInBits) TypeBase
407
407
ID : 32
408
408
);
409
409
410
- SWIFT_INLINE_BITFIELD (SILFunctionType, TypeBase, NumSILExtInfoBits+1 +3 +1 +2 +1 +1 ,
410
+ SWIFT_INLINE_BITFIELD (SILFunctionType, TypeBase, NumSILExtInfoBits+1 +4 +1 +2 +1 +1 ,
411
411
ExtInfoBits : NumSILExtInfoBits,
412
412
HasClangTypeInfo : 1 ,
413
- CalleeConvention : 3 ,
413
+ CalleeConvention : 4 ,
414
414
HasErrorResult : 1 ,
415
415
CoroutineKind : 2 ,
416
416
HasInvocationSubs : 1 ,
@@ -451,7 +451,17 @@ class alignas(1 << TypeAlignInBits) TypeBase
451
451
SWIFT_INLINE_BITFIELD_FULL (PackType, TypeBase, 32 ,
452
452
: NumPadBits,
453
453
454
- // / The number of elements of the tuple.
454
+ // / The number of elements of the pack.
455
+ Count : 32
456
+ );
457
+
458
+ SWIFT_INLINE_BITFIELD_FULL (SILPackType, TypeBase, 1 +32 ,
459
+ // / Whether elements of the pack are addresses.
460
+ ElementIsAddress : 1 ,
461
+
462
+ : NumPadBits,
463
+
464
+ // / The number of elements of the pack
455
465
Count : 32
456
466
);
457
467
@@ -3777,9 +3787,24 @@ enum class ParameterConvention : uint8_t {
3777
3787
// / This argument is passed directly. Its type is non-trivial, and the caller
3778
3788
// / guarantees its validity for the entirety of the call.
3779
3789
Direct_Guaranteed,
3790
+
3791
+ // / This argument is a value pack of mutable references to storage,
3792
+ // / which the function is being given exclusive access to. The elements
3793
+ // / must be passed indirectly.
3794
+ Pack_Inout,
3795
+
3796
+ // / This argument is a value pack, and ownership of the elements is being
3797
+ // / transferred into this function. Whether the elements are passed
3798
+ // / indirectly is recorded in the pack type.
3799
+ Pack_Owned,
3800
+
3801
+ // / This argument is a value pack, and ownership of the elements is not
3802
+ // / being transferred into this function. Whether the elements are passed
3803
+ // / indirectly is recorded in the pack type.
3804
+ Pack_Guaranteed,
3780
3805
};
3781
3806
// Check that the enum values fit inside Bits.SILFunctionType.
3782
- static_assert (unsigned (ParameterConvention::Direct_Guaranteed ) < (1 <<3 ),
3807
+ static_assert (unsigned (ParameterConvention::Pack_Guaranteed ) < (1 <<4 ),
3783
3808
"fits in Bits.SILFunctionType");
3784
3809
3785
3810
// Does this parameter convention require indirect storage? This reflects a
@@ -3796,6 +3821,9 @@ inline bool isIndirectFormalParameter(ParameterConvention conv) {
3796
3821
case ParameterConvention::Direct_Unowned:
3797
3822
case ParameterConvention::Direct_Guaranteed:
3798
3823
case ParameterConvention::Direct_Owned:
3824
+ case ParameterConvention::Pack_Inout:
3825
+ case ParameterConvention::Pack_Owned:
3826
+ case ParameterConvention::Pack_Guaranteed:
3799
3827
return false ;
3800
3828
}
3801
3829
llvm_unreachable (" covered switch isn't covered?!" );
@@ -3804,13 +3832,16 @@ inline bool isConsumedParameter(ParameterConvention conv) {
3804
3832
switch (conv) {
3805
3833
case ParameterConvention::Indirect_In:
3806
3834
case ParameterConvention::Direct_Owned:
3835
+ case ParameterConvention::Pack_Owned:
3807
3836
return true ;
3808
3837
3809
3838
case ParameterConvention::Indirect_Inout:
3810
3839
case ParameterConvention::Indirect_InoutAliasable:
3811
3840
case ParameterConvention::Direct_Unowned:
3812
3841
case ParameterConvention::Direct_Guaranteed:
3813
3842
case ParameterConvention::Indirect_In_Guaranteed:
3843
+ case ParameterConvention::Pack_Inout:
3844
+ case ParameterConvention::Pack_Guaranteed:
3814
3845
return false ;
3815
3846
}
3816
3847
llvm_unreachable (" bad convention kind" );
@@ -3823,11 +3854,34 @@ inline bool isGuaranteedParameter(ParameterConvention conv) {
3823
3854
switch (conv) {
3824
3855
case ParameterConvention::Direct_Guaranteed:
3825
3856
case ParameterConvention::Indirect_In_Guaranteed:
3857
+ case ParameterConvention::Pack_Guaranteed:
3858
+ return true ;
3859
+
3860
+ case ParameterConvention::Indirect_Inout:
3861
+ case ParameterConvention::Indirect_InoutAliasable:
3862
+ case ParameterConvention::Indirect_In:
3863
+ case ParameterConvention::Direct_Unowned:
3864
+ case ParameterConvention::Direct_Owned:
3865
+ case ParameterConvention::Pack_Inout:
3866
+ case ParameterConvention::Pack_Owned:
3867
+ return false ;
3868
+ }
3869
+ llvm_unreachable (" bad convention kind" );
3870
+ }
3871
+
3872
+ // / Returns true if conv indicates a pack parameter.
3873
+ inline bool isPackParameter (ParameterConvention conv) {
3874
+ switch (conv) {
3875
+ case ParameterConvention::Pack_Guaranteed:
3876
+ case ParameterConvention::Pack_Inout:
3877
+ case ParameterConvention::Pack_Owned:
3826
3878
return true ;
3827
3879
3880
+ case ParameterConvention::Indirect_In_Guaranteed:
3828
3881
case ParameterConvention::Indirect_Inout:
3829
3882
case ParameterConvention::Indirect_InoutAliasable:
3830
3883
case ParameterConvention::Indirect_In:
3884
+ case ParameterConvention::Direct_Guaranteed:
3831
3885
case ParameterConvention::Direct_Unowned:
3832
3886
case ParameterConvention::Direct_Owned:
3833
3887
return false ;
@@ -3906,6 +3960,10 @@ class SILParameterInfo {
3906
3960
|| getConvention () == ParameterConvention::Indirect_InoutAliasable;
3907
3961
}
3908
3962
3963
+ bool isPack () const {
3964
+ return isPackParameter (getConvention ());
3965
+ }
3966
+
3909
3967
// / True if this parameter is consumed by the callee, either
3910
3968
// / indirectly or directly.
3911
3969
bool isConsumed () const {
@@ -4027,11 +4085,18 @@ enum class ResultConvention : uint8_t {
4027
4085
// / The type must be a class or class existential type, and this
4028
4086
// / must be the only return value.
4029
4087
Autoreleased,
4088
+
4089
+ // / This value is a pack that is returned indirectly by passing a
4090
+ // / pack address (which may or may not be further indirected,
4091
+ // / depending on the pact type). The callee is responsible for
4092
+ // / leaving an initialized object in each element of the pack.
4093
+ Pack,
4030
4094
};
4031
4095
4032
4096
// Does this result require indirect storage for the purpose of reabstraction?
4033
4097
inline bool isIndirectFormalResult (ResultConvention convention) {
4034
- return convention == ResultConvention::Indirect;
4098
+ return convention == ResultConvention::Indirect ||
4099
+ convention == ResultConvention::Pack;
4035
4100
}
4036
4101
4037
4102
// / The differentiability of a SIL function type result.
@@ -5138,6 +5203,97 @@ class SILTokenType final : public TypeBase {
5138
5203
};
5139
5204
DEFINE_EMPTY_CAN_TYPE_WRAPPER (SILTokenType, Type)
5140
5205
5206
+ // / A lowered pack type which structurally carries lowered information
5207
+ // / about the pack elements.
5208
+ // /
5209
+ // / A value pack is basically treated as a unique-ownership, unmovable
5210
+ // / reference-semantics aggregate in SIL: ownership of the pack as a whole
5211
+ // / is communicated with normal borrows of the pack, and packs can only
5212
+ // / be created locally and forwarded as arguments rather than being moved
5213
+ // / in any more complex way.
5214
+ class SILPackType final : public TypeBase, public llvm::FoldingSetNode,
5215
+ private llvm::TrailingObjects<SILPackType, CanType> {
5216
+ public:
5217
+ // / Type structure not reflected in the pack element type list.
5218
+ // /
5219
+ // / In the design of this, we considered storing ownership here,
5220
+ // / but ended up just with the one bit.
5221
+ struct ExtInfo {
5222
+ bool ElementIsAddress;
5223
+
5224
+ ExtInfo (bool elementIsAddress) : ElementIsAddress(elementIsAddress) {}
5225
+ };
5226
+
5227
+ private:
5228
+ friend TrailingObjects;
5229
+ friend class ASTContext ;
5230
+ SILPackType (const ASTContext &ctx, RecursiveTypeProperties properties,
5231
+ ExtInfo info, ArrayRef<CanType> elements)
5232
+ : TypeBase (TypeKind::SILPack, &ctx, properties) {
5233
+ Bits.SILPackType .Count = elements.size ();
5234
+ Bits.SILPackType .ElementIsAddress = info.ElementIsAddress ;
5235
+ memcpy (getTrailingObjects<CanType>(), elements.data (),
5236
+ elements.size () * sizeof (CanType));
5237
+ }
5238
+
5239
+ public:
5240
+ static CanTypeWrapper<SILPackType> get (const ASTContext &ctx,
5241
+ ExtInfo info,
5242
+ ArrayRef<CanType> elements);
5243
+
5244
+ ExtInfo getExtInfo () const {
5245
+ return { isElementAddress () };
5246
+ }
5247
+
5248
+ bool isElementAddress () const {
5249
+ return Bits.SILPackType .ElementIsAddress ;
5250
+ }
5251
+
5252
+ // / Retrieves the number of elements in this pack.
5253
+ unsigned getNumElements () const { return Bits.SILPackType .Count ; }
5254
+
5255
+ // / Retrieves the type of the elements in the pack.
5256
+ ArrayRef<CanType> getElementTypes () const {
5257
+ return {getTrailingObjects<CanType>(), getNumElements ()};
5258
+ }
5259
+
5260
+ // / Returns the type of the element at the given \p index.
5261
+ // / This is a lowered SIL type.
5262
+ CanType getElementType (unsigned index) const {
5263
+ return getTrailingObjects<CanType>()[index];
5264
+ }
5265
+
5266
+ SILType getSILElementType (unsigned index) const ; // in SILType.h
5267
+
5268
+ // / Return the reduced shape of this pack. For consistency with
5269
+ // / general shape-handling routines, we produce an AST pack type
5270
+ // / as the shape, not a SIL pack type.
5271
+ CanTypeWrapper<PackType> getReducedShape () const ;
5272
+
5273
+ bool containsPackExpansionType () const ;
5274
+
5275
+ void Profile (llvm::FoldingSetNodeID &ID) const {
5276
+ Profile (ID, getExtInfo (), getElementTypes ());
5277
+ }
5278
+ static void Profile (llvm::FoldingSetNodeID &ID,
5279
+ ExtInfo info,
5280
+ ArrayRef<CanType> elements);
5281
+
5282
+ // Implement isa/cast/dyncast/etc.
5283
+ static bool classof (const TypeBase *T) {
5284
+ return T->getKind () == TypeKind::SILPack;
5285
+ }
5286
+ };
5287
+ BEGIN_CAN_TYPE_WRAPPER (SILPackType, Type)
5288
+ CanType getElementType(unsigned elementNo) const {
5289
+ return getPointer ()->getElementType (elementNo);
5290
+ }
5291
+
5292
+ ArrayRef<CanType> getElementTypes () const {
5293
+ return getPointer ()->getElementTypes ();
5294
+ }
5295
+ END_CAN_TYPE_WRAPPER (SILPackType, Type)
5296
+
5141
5297
// / A type with a special syntax that is always sugar for a library type. The
5142
5298
// / library type may have multiple base types. For unary syntax sugar, see
5143
5299
// / UnarySyntaxSugarType.
@@ -6654,6 +6810,8 @@ class PackExpansionType : public TypeBase, public llvm::FoldingSetNode {
6654
6810
const ASTContext *ctx);
6655
6811
};
6656
6812
BEGIN_CAN_TYPE_WRAPPER (PackExpansionType, Type)
6813
+ static CanPackExpansionType get (CanType pattern, CanType countType);
6814
+
6657
6815
CanType getPatternType () const {
6658
6816
return CanType (getPointer ()->getPatternType ());
6659
6817
}
0 commit comments