@@ -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,13 +3854,16 @@ 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:
3826
3858
return true ;
3827
3859
3828
3860
case ParameterConvention::Indirect_Inout:
3829
3861
case ParameterConvention::Indirect_InoutAliasable:
3830
3862
case ParameterConvention::Indirect_In:
3831
3863
case ParameterConvention::Direct_Unowned:
3832
3864
case ParameterConvention::Direct_Owned:
3865
+ case ParameterConvention::Pack_Inout:
3866
+ case ParameterConvention::Pack_Owned:
3833
3867
return false ;
3834
3868
}
3835
3869
llvm_unreachable (" bad convention kind" );
@@ -5138,6 +5172,97 @@ class SILTokenType final : public TypeBase {
5138
5172
};
5139
5173
DEFINE_EMPTY_CAN_TYPE_WRAPPER (SILTokenType, Type)
5140
5174
5175
+ // / A lowered pack type which structurally carries lowered information
5176
+ // / about the pack elements.
5177
+ // /
5178
+ // / A value pack is basically treated as a unique-ownership, unmovable
5179
+ // / reference-semantics aggregate in SIL: ownership of the pack as a whole
5180
+ // / is communicated with normal borrows of the pack, and packs can only
5181
+ // / be created locally and forwarded as arguments rather than being moved
5182
+ // / in any more complex way.
5183
+ class SILPackType final : public TypeBase, public llvm::FoldingSetNode,
5184
+ private llvm::TrailingObjects<SILPackType, CanType> {
5185
+ public:
5186
+ // / Type structure not reflected in the pack element type list.
5187
+ // /
5188
+ // / In the design of this, we considered storing ownership here,
5189
+ // / but ended up just with the one bit.
5190
+ struct ExtInfo {
5191
+ bool ElementIsAddress;
5192
+
5193
+ ExtInfo (bool elementIsAddress) : ElementIsAddress(elementIsAddress) {}
5194
+ };
5195
+
5196
+ private:
5197
+ friend TrailingObjects;
5198
+ friend class ASTContext ;
5199
+ SILPackType (const ASTContext &ctx, RecursiveTypeProperties properties,
5200
+ ExtInfo info, ArrayRef<CanType> elements)
5201
+ : TypeBase (TypeKind::SILPack, &ctx, properties) {
5202
+ Bits.SILPackType .Count = elements.size ();
5203
+ Bits.SILPackType .ElementIsAddress = info.ElementIsAddress ;
5204
+ memcpy (getTrailingObjects<CanType>(), elements.data (),
5205
+ elements.size () * sizeof (CanType));
5206
+ }
5207
+
5208
+ public:
5209
+ static CanTypeWrapper<SILPackType> get (const ASTContext &ctx,
5210
+ ExtInfo info,
5211
+ ArrayRef<CanType> elements);
5212
+
5213
+ ExtInfo getExtInfo () const {
5214
+ return { isElementAddress () };
5215
+ }
5216
+
5217
+ bool isElementAddress () const {
5218
+ return Bits.SILPackType .ElementIsAddress ;
5219
+ }
5220
+
5221
+ // / Retrieves the number of elements in this pack.
5222
+ unsigned getNumElements () const { return Bits.SILPackType .Count ; }
5223
+
5224
+ // / Retrieves the type of the elements in the pack.
5225
+ ArrayRef<CanType> getElementTypes () const {
5226
+ return {getTrailingObjects<CanType>(), getNumElements ()};
5227
+ }
5228
+
5229
+ // / Returns the type of the element at the given \p index.
5230
+ // / This is a lowered SIL type.
5231
+ CanType getElementType (unsigned index) const {
5232
+ return getTrailingObjects<CanType>()[index];
5233
+ }
5234
+
5235
+ SILType getSILElementType (unsigned index) const ; // in SILType.h
5236
+
5237
+ // / Return the reduced shape of this pack. For consistency with
5238
+ // / general shape-handling routines, we produce an AST pack type
5239
+ // / as the shape, not a SIL pack type.
5240
+ CanTypeWrapper<PackType> getReducedShape () const ;
5241
+
5242
+ bool containsPackExpansionType () const ;
5243
+
5244
+ void Profile (llvm::FoldingSetNodeID &ID) const {
5245
+ Profile (ID, getExtInfo (), getElementTypes ());
5246
+ }
5247
+ static void Profile (llvm::FoldingSetNodeID &ID,
5248
+ ExtInfo info,
5249
+ ArrayRef<CanType> elements);
5250
+
5251
+ // Implement isa/cast/dyncast/etc.
5252
+ static bool classof (const TypeBase *T) {
5253
+ return T->getKind () == TypeKind::SILPack;
5254
+ }
5255
+ };
5256
+ BEGIN_CAN_TYPE_WRAPPER (SILPackType, Type)
5257
+ CanType getElementType(unsigned elementNo) const {
5258
+ return getPointer ()->getElementType (elementNo);
5259
+ }
5260
+
5261
+ ArrayRef<CanType> getElementTypes () const {
5262
+ return getPointer ()->getElementTypes ();
5263
+ }
5264
+ END_CAN_TYPE_WRAPPER (SILPackType, Type)
5265
+
5141
5266
// / A type with a special syntax that is always sugar for a library type. The
5142
5267
// / library type may have multiple base types. For unary syntax sugar, see
5143
5268
// / UnarySyntaxSugarType.
@@ -6654,6 +6779,8 @@ class PackExpansionType : public TypeBase, public llvm::FoldingSetNode {
6654
6779
const ASTContext *ctx);
6655
6780
};
6656
6781
BEGIN_CAN_TYPE_WRAPPER (PackExpansionType, Type)
6782
+ static CanPackExpansionType get (CanType pattern, CanType countType);
6783
+
6657
6784
CanType getPatternType () const {
6658
6785
return CanType (getPointer ()->getPatternType ());
6659
6786
}
0 commit comments