@@ -71,6 +71,7 @@ class NominalTypeDecl;
71
71
class GenericTypeDecl ;
72
72
class EnumDecl ;
73
73
class EnumElementDecl ;
74
+ class SILFunctionType ;
74
75
class StructDecl ;
75
76
class ProtocolDecl ;
76
77
class TypeVariableType ;
@@ -81,6 +82,8 @@ class ProtocolConformance;
81
82
enum PointerTypeKind : unsigned ;
82
83
struct ValueOwnershipKind ;
83
84
85
+ typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
86
+
84
87
enum class TypeKind : uint8_t {
85
88
#define TYPE (id, parent ) id,
86
89
#define LAST_TYPE (id ) Last_Type = id,
@@ -3409,9 +3412,19 @@ class SILParameterInfo {
3409
3412
assert (type->isLegalSILType () && " SILParameterInfo has illegal SIL type" );
3410
3413
}
3411
3414
3412
- CanType getType () const {
3415
+ // / Return the unsubstituted parameter type that describes the abstract
3416
+ // / calling convention of the parameter.
3417
+ // /
3418
+ // / For most purposes, you probably want \c getArgumentType .
3419
+ CanType getInterfaceType () const {
3413
3420
return TypeAndConvention.getPointer ();
3414
3421
}
3422
+
3423
+ // / Return the type of a call argument matching this parameter.
3424
+ // /
3425
+ // / \c t must refer back to the function type this is a parameter for.
3426
+ CanType getArgumentType (SILModule &M,
3427
+ const SILFunctionType *t) const ;
3415
3428
ParameterConvention getConvention () const {
3416
3429
return TypeAndConvention.getInt ();
3417
3430
}
@@ -3456,10 +3469,12 @@ class SILParameterInfo {
3456
3469
// / storage. Therefore they will be passed using an indirect formal
3457
3470
// / convention, and this method will return an address type. However, in
3458
3471
// / canonical SIL the opaque arguments might not have an address type.
3459
- SILType getSILStorageType () const ; // in SILFunctionConventions.h
3472
+ SILType getSILStorageType (SILModule &M,
3473
+ const SILFunctionType *t) const ; // in SILFunctionConventions.h
3474
+ SILType getSILStorageInterfaceType () const ;
3460
3475
3461
3476
// / Return a version of this parameter info with the type replaced.
3462
- SILParameterInfo getWithType (CanType type) const {
3477
+ SILParameterInfo getWithInterfaceType (CanType type) const {
3463
3478
return SILParameterInfo (type, getConvention ());
3464
3479
}
3465
3480
@@ -3470,11 +3485,11 @@ class SILParameterInfo {
3470
3485
// / Type::transform does.
3471
3486
template <typename F>
3472
3487
SILParameterInfo map (const F &fn) const {
3473
- return getWithType (fn (getType ()));
3488
+ return getWithInterfaceType (fn (getInterfaceType ()));
3474
3489
}
3475
3490
3476
3491
void profile (llvm::FoldingSetNodeID &id) {
3477
- id.AddPointer (getType ().getPointer ());
3492
+ id.AddPointer (getInterfaceType ().getPointer ());
3478
3493
id.AddInteger ((unsigned )getConvention ());
3479
3494
}
3480
3495
@@ -3489,7 +3504,8 @@ class SILParameterInfo {
3489
3504
}
3490
3505
3491
3506
bool operator ==(SILParameterInfo rhs) const {
3492
- return getType () == rhs.getType () && getConvention () == rhs.getConvention ();
3507
+ return getInterfaceType () == rhs.getInterfaceType ()
3508
+ && getConvention () == rhs.getConvention ();
3493
3509
}
3494
3510
bool operator !=(SILParameterInfo rhs) const {
3495
3511
return !(*this == rhs);
@@ -3541,9 +3557,20 @@ class SILResultInfo {
3541
3557
assert (type->isLegalSILType () && " SILResultInfo has illegal SIL type" );
3542
3558
}
3543
3559
3544
- CanType getType () const {
3560
+ // / Return the unsubstituted parameter type that describes the abstract
3561
+ // / calling convention of the parameter.
3562
+ // /
3563
+ // / For most purposes, you probably want \c getReturnValueType .
3564
+ CanType getInterfaceType () const {
3545
3565
return TypeAndConvention.getPointer ();
3546
3566
}
3567
+
3568
+ // / The type of a return value corresponding to this result.
3569
+ // /
3570
+ // / \c t must refer back to the function type this is a parameter for.
3571
+ CanType getReturnValueType (SILModule &M,
3572
+ const SILFunctionType *t) const ;
3573
+
3547
3574
ResultConvention getConvention () const {
3548
3575
return TypeAndConvention.getInt ();
3549
3576
}
@@ -3553,10 +3580,11 @@ class SILResultInfo {
3553
3580
// / storage. Therefore they will be returned using an indirect formal
3554
3581
// / convention, and this method will return an address type. However, in
3555
3582
// / canonical SIL the opaque results might not have an address type.
3556
- SILType getSILStorageType () const ; // in SILFunctionConventions.h
3557
-
3583
+ SILType getSILStorageType (SILModule &M,
3584
+ const SILFunctionType *t) const ; // in SILFunctionConventions.h
3585
+ SILType getSILStorageInterfaceType () const ;
3558
3586
// / Return a version of this result info with the type replaced.
3559
- SILResultInfo getWithType (CanType type) const {
3587
+ SILResultInfo getWithInterfaceType (CanType type) const {
3560
3588
return SILResultInfo (type, getConvention ());
3561
3589
}
3562
3590
@@ -3577,7 +3605,7 @@ class SILResultInfo {
3577
3605
// / Type::transform does.
3578
3606
template <typename F>
3579
3607
SILResultInfo map (F &&fn) const {
3580
- return getWithType (fn (getType ()));
3608
+ return getWithInterfaceType (fn (getInterfaceType ()));
3581
3609
}
3582
3610
3583
3611
void profile (llvm::FoldingSetNodeID &id) {
@@ -3616,13 +3644,13 @@ class SILYieldInfo : public SILParameterInfo {
3616
3644
: SILParameterInfo(type, conv) {
3617
3645
}
3618
3646
3619
- SILYieldInfo getWithType (CanType type) const {
3647
+ SILYieldInfo getWithInterfaceType (CanType type) const {
3620
3648
return SILYieldInfo (type, getConvention ());
3621
3649
}
3622
3650
3623
3651
template <typename F>
3624
3652
SILYieldInfo map (const F &fn) const {
3625
- return getWithType (fn (getType ()));
3653
+ return getWithInterfaceType (fn (getInterfaceType ()));
3626
3654
}
3627
3655
};
3628
3656
@@ -3641,8 +3669,6 @@ enum class SILCoroutineKind : uint8_t {
3641
3669
YieldMany,
3642
3670
};
3643
3671
3644
- class SILFunctionType ;
3645
- typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
3646
3672
class SILFunctionConventions ;
3647
3673
3648
3674
// / SILFunctionType - The lowered type of a function value, suitable
@@ -3799,8 +3825,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3799
3825
// CanType? // if !isCoro && NumAnyResults > 1, formal result cache
3800
3826
// CanType? // if !isCoro && NumAnyResults > 1, all result cache
3801
3827
3802
- CanGenericSignature GenericSig ;
3828
+ llvm::PointerIntPair< CanGenericSignature, 1 , bool > GenericSigAndIsImplied ;
3803
3829
Optional<ProtocolConformanceRef> WitnessMethodConformance;
3830
+ SubstitutionMap Substitutions;
3804
3831
3805
3832
MutableArrayRef<SILParameterInfo> getMutableParameters () {
3806
3833
return {getTrailingObjects<SILParameterInfo>(), NumParameters};
@@ -3861,6 +3888,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3861
3888
ArrayRef<SILYieldInfo> yieldResults,
3862
3889
ArrayRef<SILResultInfo> normalResults,
3863
3890
Optional<SILResultInfo> errorResult,
3891
+ SubstitutionMap substitutions,
3892
+ bool genericSigIsImplied,
3864
3893
const ASTContext &ctx,
3865
3894
RecursiveTypeProperties properties,
3866
3895
Optional<ProtocolConformanceRef> witnessMethodConformance);
@@ -3874,6 +3903,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3874
3903
ArrayRef<SILYieldInfo> interfaceYields,
3875
3904
ArrayRef<SILResultInfo> interfaceResults,
3876
3905
Optional<SILResultInfo> interfaceErrorResult,
3906
+ SubstitutionMap substitutions,
3907
+ bool genericSigIsImplied,
3877
3908
const ASTContext &ctx,
3878
3909
Optional<ProtocolConformanceRef> witnessMethodConformance = None);
3879
3910
@@ -3894,7 +3925,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3894
3925
// / - a single indirect result and no direct results.
3895
3926
// /
3896
3927
// / If the result is formally indirect, return the empty tuple.
3897
- SILType getFormalCSemanticResult ();
3928
+ SILType getFormalCSemanticResult (SILModule &M );
3898
3929
3899
3930
// / Return the convention under which the callee is passed, if this
3900
3931
// / is a thick non-block callee.
@@ -4003,14 +4034,15 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4003
4034
// / this function depends on the current SIL stage and is known by
4004
4035
// / SILFunctionConventions. It may be a wider tuple that includes formally
4005
4036
// / indirect results.
4006
- SILType getDirectFormalResultsType ();
4037
+ SILType getDirectFormalResultsType (SILModule &M );
4007
4038
4008
4039
// / Get a single non-address SILType for all SIL results regardless of whether
4009
4040
// / they are formally indirect. The actual SIL result type of an apply
4010
4041
// / instruction that calls this function depends on the current SIL stage and
4011
4042
// / is known by SILFunctionConventions. It may be a narrower tuple that omits
4012
4043
// / formally indirect results.
4013
- SILType getAllResultsType ();
4044
+ SILType getAllResultsSubstType (SILModule &M);
4045
+ SILType getAllResultsInterfaceType ();
4014
4046
4015
4047
// / Does this function have a blessed Swift-native error result?
4016
4048
bool hasErrorResult () const {
@@ -4041,15 +4073,36 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4041
4073
return getParameters ().back ();
4042
4074
}
4043
4075
4044
- bool isPolymorphic () const { return !GenericSig.isNull (); }
4045
- CanGenericSignature getGenericSignature () const { return GenericSig; }
4076
+ // / Get the generic signature used to apply the substitutions of a substituted function type
4077
+ CanGenericSignature getSubstGenericSignature () const {
4078
+ return GenericSigAndIsImplied.getPointer ();
4079
+ }
4080
+ // / Get the generic signature used by callers to invoke the function.
4081
+ CanGenericSignature getInvocationGenericSignature () const {
4082
+ if (isGenericSignatureImplied ()) {
4083
+ return CanGenericSignature ();
4084
+ } else {
4085
+ return getSubstGenericSignature ();
4086
+ }
4087
+ }
4088
+
4089
+ bool isGenericSignatureImplied () const {
4090
+ return GenericSigAndIsImplied.getInt ();
4091
+ }
4092
+ SubstitutionMap getSubstitutions () const {
4093
+ return Substitutions;
4094
+ }
4095
+
4096
+ bool isPolymorphic () const {
4097
+ return !getInvocationGenericSignature ().isNull ();
4098
+ }
4046
4099
4047
- CanType getSelfInstanceType () const ;
4100
+ CanType getSelfInstanceType (SILModule &M ) const ;
4048
4101
4049
4102
// / If this is a @convention(witness_method) function with a class
4050
4103
// / constrained self parameter, return the class constraint for the
4051
4104
// / Self type.
4052
- ClassDecl *getWitnessMethodClass () const ;
4105
+ ClassDecl *getWitnessMethodClass (SILModule &M ) const ;
4053
4106
4054
4107
// / If this is a @convention(witness_method) function, return the conformance
4055
4108
// / for which the method is a witness.
@@ -4095,7 +4148,11 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4095
4148
getRepresentation () == SILFunctionTypeRepresentation::Thick;
4096
4149
}
4097
4150
4098
- bool isNoReturnFunction () const ; // Defined in SILType.cpp
4151
+ bool isNoReturnFunction (SILModule &M) const ; // Defined in SILType.cpp
4152
+
4153
+ // / Create a SILFunctionType with the same parameters, results, and attributes as this one, but with
4154
+ // / a different set of substitutions.
4155
+ CanSILFunctionType withSubstitutions (SubstitutionMap subs) const ;
4099
4156
4100
4157
class ABICompatibilityCheckResult {
4101
4158
friend class SILFunctionType ;
@@ -4139,19 +4196,24 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4139
4196
// / assertions are disabled, this just returns true.
4140
4197
ABICompatibilityCheckResult
4141
4198
isABICompatibleWith (CanSILFunctionType other,
4142
- SILFunction * context = nullptr ) const ;
4199
+ SILFunction & context) const ;
4143
4200
4144
4201
CanSILFunctionType substGenericArgs (SILModule &silModule,
4145
4202
SubstitutionMap subs);
4146
4203
CanSILFunctionType substGenericArgs (SILModule &silModule,
4147
4204
TypeSubstitutionFn subs,
4148
4205
LookupConformanceFn conformances);
4149
4206
4207
+ SILType substInterfaceType (SILModule &M,
4208
+ SILType interfaceType) const ;
4209
+
4150
4210
void Profile (llvm::FoldingSetNodeID &ID) {
4151
- Profile (ID, getGenericSignature (), getExtInfo (), getCoroutineKind (),
4211
+ Profile (ID, getSubstGenericSignature (), getExtInfo (), getCoroutineKind (),
4152
4212
getCalleeConvention (), getParameters (), getYields (),
4153
4213
getResults (), getOptionalErrorResult (),
4154
- getWitnessMethodConformanceOrNone ());
4214
+ getWitnessMethodConformanceOrNone (),
4215
+ isGenericSignatureImplied (),
4216
+ getSubstitutions ());
4155
4217
}
4156
4218
static void Profile (llvm::FoldingSetNodeID &ID,
4157
4219
GenericSignature genericSig,
@@ -4162,7 +4224,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4162
4224
ArrayRef<SILYieldInfo> yields,
4163
4225
ArrayRef<SILResultInfo> results,
4164
4226
Optional<SILResultInfo> errorResult,
4165
- Optional<ProtocolConformanceRef> conformance);
4227
+ Optional<ProtocolConformanceRef> conformance,
4228
+ bool isGenericSigImplied,
4229
+ SubstitutionMap substitutions);
4166
4230
4167
4231
// Implement isa/cast/dyncast/etc.
4168
4232
static bool classof (const TypeBase *T) {
0 commit comments