@@ -122,6 +122,7 @@ enum class ConventionsKind : uint8_t {
122
122
CFunction = 4 ,
123
123
SelectorFamily = 5 ,
124
124
Deallocator = 6 ,
125
+ Capture = 7 ,
125
126
};
126
127
127
128
class Conventions {
@@ -359,9 +360,6 @@ enum class ConventionsKind : uint8_t {
359
360
if (isa<InOutType>(substType)) {
360
361
assert (origType.isOpaque () || origType.getAs <InOutType>());
361
362
convention = ParameterConvention::Indirect_Inout;
362
- } else if (isa<LValueType>(substType)) {
363
- assert (origType.isOpaque () || origType.getAs <LValueType>());
364
- convention = ParameterConvention::Indirect_InoutAliasable;
365
363
} else if (isPassedIndirectly (origType, substType, substTL)) {
366
364
convention = Convs.getIndirectParameter (origParamIndex, origType);
367
365
assert (isIndirectParameter (convention));
@@ -430,7 +428,8 @@ static CanSILFunctionType getSILFunctionType(SILModule &M,
430
428
CanAnyFunctionType substFnInterfaceType,
431
429
AnyFunctionType::ExtInfo extInfo,
432
430
const Conventions &conventions,
433
- const Optional<ForeignErrorConvention> &foreignError) {
431
+ const Optional<ForeignErrorConvention> &foreignError,
432
+ Optional<SILDeclRef> constant) {
434
433
SmallVector<SILParameterInfo, 8 > inputs;
435
434
436
435
// Per above, only fully honor opaqueness in the abstraction pattern
@@ -564,7 +563,92 @@ static CanSILFunctionType getSILFunctionType(SILModule &M,
564
563
substFnInterfaceType.getInput (),
565
564
extInfo);
566
565
}
567
-
566
+
567
+ // Lower the capture context parameters, if any.
568
+ if (constant)
569
+ if (auto function = constant->getAnyFunctionRef ()) {
570
+ auto &Types = M.Types ;
571
+ auto loweredCaptures = Types.getLoweredLocalCaptures (*function);
572
+
573
+ for (auto capture : loweredCaptures.getCaptures ()) {
574
+ auto *VD = capture.getDecl ();
575
+ auto type = VD->getType ()->getCanonicalType ();
576
+
577
+ type = Types.getInterfaceTypeOutOfContext (type,
578
+ function->getAsDeclContext ());
579
+
580
+ auto loweredTy = Types.getLoweredType (
581
+ AbstractionPattern (genericSig, type), type);
582
+
583
+ switch (Types.getDeclCaptureKind (capture)) {
584
+ case CaptureKind::None:
585
+ break ;
586
+ case CaptureKind::Constant: {
587
+ class CaptureConventions final : public Conventions {
588
+ public:
589
+ ParameterConvention getIndirectParameter (unsigned index,
590
+ const AbstractionPattern &type)
591
+ const override {
592
+ return ParameterConvention::Indirect_In;
593
+ }
594
+ ParameterConvention getDirectParameter (unsigned index,
595
+ const AbstractionPattern &type)
596
+ const override {
597
+ return ParameterConvention::Direct_Owned;
598
+ }
599
+ ParameterConvention getCallee () const override {
600
+ llvm_unreachable (" captures are never callees" );
601
+ }
602
+ ResultConvention getResult (const TypeLowering &) const override {
603
+ llvm_unreachable (" captures are never results" );
604
+ }
605
+ ParameterConvention getIndirectSelfParameter (
606
+ const AbstractionPattern &type)
607
+ const override {
608
+ llvm_unreachable (" captures are never self" );
609
+ }
610
+ ParameterConvention getDirectSelfParameter (
611
+ const AbstractionPattern &type)
612
+ const override {
613
+ llvm_unreachable (" captures are never self" );
614
+ }
615
+
616
+ CaptureConventions () : Conventions(ConventionsKind::Capture) {}
617
+
618
+ static bool classof (const Conventions *C) {
619
+ return C->getKind () == ConventionsKind::Capture;
620
+ }
621
+ };
622
+
623
+ // Constants are captured by value. Destructure like a value parameter.
624
+ Optional<ForeignErrorConvention> foreignError;
625
+ DestructureInputs DestructureCaptures (M, CaptureConventions (),
626
+ foreignError, inputs);
627
+ DestructureCaptures.destructure (AbstractionPattern (genericSig, type),
628
+ type, extInfo);
629
+ break ;
630
+ }
631
+ case CaptureKind::Box: {
632
+ // Lvalues are captured as a box that owns the captured value.
633
+ SILType ty = loweredTy.getAddressType ();
634
+ CanType boxTy = SILBoxType::get (ty.getSwiftRValueType ());
635
+ auto param = SILParameterInfo (boxTy,
636
+ ParameterConvention::Direct_Owned);
637
+ inputs.push_back (param);
638
+ break ;
639
+ }
640
+ case CaptureKind::StorageAddress: {
641
+ // Non-escaping lvalues are captured as the address of the value.
642
+ SILType ty = loweredTy.getAddressType ();
643
+ auto param = SILParameterInfo (ty.getSwiftRValueType (),
644
+ ParameterConvention::Indirect_InoutAliasable);
645
+ inputs.push_back (param);
646
+ break ;
647
+ }
648
+ }
649
+ }
650
+ }
651
+
568
652
auto calleeConvention = ParameterConvention::Direct_Unowned;
569
653
if (extInfo.hasContext ())
570
654
calleeConvention = conventions.getCallee ();
@@ -730,17 +814,19 @@ namespace {
730
814
}
731
815
732
816
static CanSILFunctionType getNativeSILFunctionType (SILModule &M,
733
- AbstractionPattern origType,
734
- CanAnyFunctionType substType,
735
- CanAnyFunctionType substInterfaceType,
736
- AnyFunctionType::ExtInfo extInfo,
737
- SILDeclRef::Kind kind) {
817
+ AbstractionPattern origType,
818
+ CanAnyFunctionType substType,
819
+ CanAnyFunctionType substInterfaceType,
820
+ AnyFunctionType::ExtInfo extInfo,
821
+ Optional<SILDeclRef> constant,
822
+ SILDeclRef::Kind kind) {
738
823
switch (extInfo.getSILRepresentation ()) {
739
824
case SILFunctionType::Representation::Block:
740
825
case SILFunctionType::Representation::CFunctionPointer:
826
+ // TODO: Ought to support captures in block funcs.
741
827
return getSILFunctionType (M, origType, substType, substInterfaceType,
742
828
extInfo, DefaultBlockConventions (),
743
- None);
829
+ None, constant );
744
830
745
831
case SILFunctionType::Representation::Thin:
746
832
case SILFunctionType::Representation::ObjCMethod:
@@ -751,7 +837,7 @@ static CanSILFunctionType getNativeSILFunctionType(SILModule &M,
751
837
case SILDeclRef::Kind::Initializer:
752
838
return getSILFunctionType (M, origType, substType, substInterfaceType,
753
839
extInfo, DefaultInitializerConventions (),
754
- None);
840
+ None, constant );
755
841
756
842
case SILDeclRef::Kind::Func:
757
843
case SILDeclRef::Kind::Allocator:
@@ -764,10 +850,11 @@ static CanSILFunctionType getNativeSILFunctionType(SILModule &M,
764
850
case SILDeclRef::Kind::EnumElement:
765
851
return getSILFunctionType (M, origType, substType, substInterfaceType,
766
852
extInfo, DefaultConventions (),
767
- None);
853
+ None, constant );
768
854
case SILDeclRef::Kind::Deallocator:
769
855
return getSILFunctionType (M, origType, substType, substInterfaceType,
770
- extInfo, DeallocatorConventions (), None);
856
+ extInfo, DeallocatorConventions (), None,
857
+ constant);
771
858
}
772
859
}
773
860
}
@@ -789,7 +876,7 @@ CanSILFunctionType swift::getNativeSILFunctionType(SILModule &M,
789
876
extInfo = substType->getExtInfo ();
790
877
}
791
878
return ::getNativeSILFunctionType (M, origType, substType, substInterfaceType,
792
- extInfo, kind);
879
+ extInfo, None, kind);
793
880
}
794
881
795
882
// ===----------------------------------------------------------------------===//
@@ -1101,15 +1188,15 @@ getSILFunctionTypeForClangDecl(SILModule &M, const clang::Decl *clangDecl,
1101
1188
AbstractionPattern::getObjCMethod (origType, method, foreignError);
1102
1189
return getSILFunctionType (M, origPattern, substType, substInterfaceType,
1103
1190
extInfo, ObjCMethodConventions (method),
1104
- foreignError);
1191
+ foreignError, None );
1105
1192
}
1106
1193
1107
1194
if (auto func = dyn_cast<clang::FunctionDecl>(clangDecl)) {
1108
1195
AbstractionPattern origPattern (origType,
1109
1196
func->getType ().getTypePtr ());
1110
1197
return getSILFunctionType (M, origPattern, substType, substInterfaceType,
1111
1198
extInfo, CFunctionConventions (func),
1112
- foreignError);
1199
+ foreignError, None );
1113
1200
}
1114
1201
1115
1202
llvm_unreachable (" call to unknown kind of C function" );
@@ -1297,7 +1384,7 @@ getSILFunctionTypeForSelectorFamily(SILModule &M, SelectorFamily family,
1297
1384
substType, substInterfaceType,
1298
1385
extInfo,
1299
1386
SelectorFamilyConventions (family),
1300
- foreignError);
1387
+ foreignError, None );
1301
1388
}
1302
1389
1303
1390
static CanSILFunctionType
@@ -1334,10 +1421,11 @@ getUncachedSILFunctionTypeForConstant(SILModule &M, SILDeclRef constant,
1334
1421
1335
1422
if (!constant.isForeign ) {
1336
1423
return getNativeSILFunctionType (M, AbstractionPattern (origLoweredType),
1337
- substLoweredType,
1338
- substLoweredInterfaceType,
1339
- extInfo,
1340
- constant.kind );
1424
+ substLoweredType,
1425
+ substLoweredInterfaceType,
1426
+ extInfo,
1427
+ constant,
1428
+ constant.kind );
1341
1429
}
1342
1430
1343
1431
Optional<ForeignErrorConvention> foreignError;
0 commit comments