Skip to content

Commit 1a1d9e6

Browse files
authored
Merge pull request #27887 from jckarter/subst-sil-function-type-interface
SIL: Add fields to SILFunctionType for substituted function types.
2 parents 6536f59 + 03c7919 commit 1a1d9e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1173
-645
lines changed

include/swift/AST/Types.h

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class NominalTypeDecl;
7171
class GenericTypeDecl;
7272
class EnumDecl;
7373
class EnumElementDecl;
74+
class SILFunctionType;
7475
class StructDecl;
7576
class ProtocolDecl;
7677
class TypeVariableType;
@@ -81,6 +82,8 @@ class ProtocolConformance;
8182
enum PointerTypeKind : unsigned;
8283
struct ValueOwnershipKind;
8384

85+
typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
86+
8487
enum class TypeKind : uint8_t {
8588
#define TYPE(id, parent) id,
8689
#define LAST_TYPE(id) Last_Type = id,
@@ -3409,9 +3412,19 @@ class SILParameterInfo {
34093412
assert(type->isLegalSILType() && "SILParameterInfo has illegal SIL type");
34103413
}
34113414

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 {
34133420
return TypeAndConvention.getPointer();
34143421
}
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;
34153428
ParameterConvention getConvention() const {
34163429
return TypeAndConvention.getInt();
34173430
}
@@ -3456,10 +3469,12 @@ class SILParameterInfo {
34563469
/// storage. Therefore they will be passed using an indirect formal
34573470
/// convention, and this method will return an address type. However, in
34583471
/// 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;
34603475

34613476
/// Return a version of this parameter info with the type replaced.
3462-
SILParameterInfo getWithType(CanType type) const {
3477+
SILParameterInfo getWithInterfaceType(CanType type) const {
34633478
return SILParameterInfo(type, getConvention());
34643479
}
34653480

@@ -3470,11 +3485,11 @@ class SILParameterInfo {
34703485
/// Type::transform does.
34713486
template<typename F>
34723487
SILParameterInfo map(const F &fn) const {
3473-
return getWithType(fn(getType()));
3488+
return getWithInterfaceType(fn(getInterfaceType()));
34743489
}
34753490

34763491
void profile(llvm::FoldingSetNodeID &id) {
3477-
id.AddPointer(getType().getPointer());
3492+
id.AddPointer(getInterfaceType().getPointer());
34783493
id.AddInteger((unsigned)getConvention());
34793494
}
34803495

@@ -3489,7 +3504,8 @@ class SILParameterInfo {
34893504
}
34903505

34913506
bool operator==(SILParameterInfo rhs) const {
3492-
return getType() == rhs.getType() && getConvention() == rhs.getConvention();
3507+
return getInterfaceType() == rhs.getInterfaceType()
3508+
&& getConvention() == rhs.getConvention();
34933509
}
34943510
bool operator!=(SILParameterInfo rhs) const {
34953511
return !(*this == rhs);
@@ -3541,9 +3557,20 @@ class SILResultInfo {
35413557
assert(type->isLegalSILType() && "SILResultInfo has illegal SIL type");
35423558
}
35433559

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 {
35453565
return TypeAndConvention.getPointer();
35463566
}
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+
35473574
ResultConvention getConvention() const {
35483575
return TypeAndConvention.getInt();
35493576
}
@@ -3553,10 +3580,11 @@ class SILResultInfo {
35533580
/// storage. Therefore they will be returned using an indirect formal
35543581
/// convention, and this method will return an address type. However, in
35553582
/// 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;
35583586
/// Return a version of this result info with the type replaced.
3559-
SILResultInfo getWithType(CanType type) const {
3587+
SILResultInfo getWithInterfaceType(CanType type) const {
35603588
return SILResultInfo(type, getConvention());
35613589
}
35623590

@@ -3577,7 +3605,7 @@ class SILResultInfo {
35773605
/// Type::transform does.
35783606
template <typename F>
35793607
SILResultInfo map(F &&fn) const {
3580-
return getWithType(fn(getType()));
3608+
return getWithInterfaceType(fn(getInterfaceType()));
35813609
}
35823610

35833611
void profile(llvm::FoldingSetNodeID &id) {
@@ -3616,13 +3644,13 @@ class SILYieldInfo : public SILParameterInfo {
36163644
: SILParameterInfo(type, conv) {
36173645
}
36183646

3619-
SILYieldInfo getWithType(CanType type) const {
3647+
SILYieldInfo getWithInterfaceType(CanType type) const {
36203648
return SILYieldInfo(type, getConvention());
36213649
}
36223650

36233651
template<typename F>
36243652
SILYieldInfo map(const F &fn) const {
3625-
return getWithType(fn(getType()));
3653+
return getWithInterfaceType(fn(getInterfaceType()));
36263654
}
36273655
};
36283656

@@ -3641,8 +3669,6 @@ enum class SILCoroutineKind : uint8_t {
36413669
YieldMany,
36423670
};
36433671

3644-
class SILFunctionType;
3645-
typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
36463672
class SILFunctionConventions;
36473673

36483674
/// SILFunctionType - The lowered type of a function value, suitable
@@ -3799,8 +3825,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
37993825
// CanType? // if !isCoro && NumAnyResults > 1, formal result cache
38003826
// CanType? // if !isCoro && NumAnyResults > 1, all result cache
38013827

3802-
CanGenericSignature GenericSig;
3828+
llvm::PointerIntPair<CanGenericSignature, 1, bool> GenericSigAndIsImplied;
38033829
Optional<ProtocolConformanceRef> WitnessMethodConformance;
3830+
SubstitutionMap Substitutions;
38043831

38053832
MutableArrayRef<SILParameterInfo> getMutableParameters() {
38063833
return {getTrailingObjects<SILParameterInfo>(), NumParameters};
@@ -3861,6 +3888,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
38613888
ArrayRef<SILYieldInfo> yieldResults,
38623889
ArrayRef<SILResultInfo> normalResults,
38633890
Optional<SILResultInfo> errorResult,
3891+
SubstitutionMap substitutions,
3892+
bool genericSigIsImplied,
38643893
const ASTContext &ctx,
38653894
RecursiveTypeProperties properties,
38663895
Optional<ProtocolConformanceRef> witnessMethodConformance);
@@ -3874,6 +3903,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
38743903
ArrayRef<SILYieldInfo> interfaceYields,
38753904
ArrayRef<SILResultInfo> interfaceResults,
38763905
Optional<SILResultInfo> interfaceErrorResult,
3906+
SubstitutionMap substitutions,
3907+
bool genericSigIsImplied,
38773908
const ASTContext &ctx,
38783909
Optional<ProtocolConformanceRef> witnessMethodConformance = None);
38793910

@@ -3894,7 +3925,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
38943925
/// - a single indirect result and no direct results.
38953926
///
38963927
/// If the result is formally indirect, return the empty tuple.
3897-
SILType getFormalCSemanticResult();
3928+
SILType getFormalCSemanticResult(SILModule &M);
38983929

38993930
/// Return the convention under which the callee is passed, if this
39003931
/// is a thick non-block callee.
@@ -4003,14 +4034,15 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
40034034
/// this function depends on the current SIL stage and is known by
40044035
/// SILFunctionConventions. It may be a wider tuple that includes formally
40054036
/// indirect results.
4006-
SILType getDirectFormalResultsType();
4037+
SILType getDirectFormalResultsType(SILModule &M);
40074038

40084039
/// Get a single non-address SILType for all SIL results regardless of whether
40094040
/// they are formally indirect. The actual SIL result type of an apply
40104041
/// instruction that calls this function depends on the current SIL stage and
40114042
/// is known by SILFunctionConventions. It may be a narrower tuple that omits
40124043
/// formally indirect results.
4013-
SILType getAllResultsType();
4044+
SILType getAllResultsSubstType(SILModule &M);
4045+
SILType getAllResultsInterfaceType();
40144046

40154047
/// Does this function have a blessed Swift-native error result?
40164048
bool hasErrorResult() const {
@@ -4041,15 +4073,36 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
40414073
return getParameters().back();
40424074
}
40434075

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+
}
40464099

4047-
CanType getSelfInstanceType() const;
4100+
CanType getSelfInstanceType(SILModule &M) const;
40484101

40494102
/// If this is a @convention(witness_method) function with a class
40504103
/// constrained self parameter, return the class constraint for the
40514104
/// Self type.
4052-
ClassDecl *getWitnessMethodClass() const;
4105+
ClassDecl *getWitnessMethodClass(SILModule &M) const;
40534106

40544107
/// If this is a @convention(witness_method) function, return the conformance
40554108
/// for which the method is a witness.
@@ -4095,7 +4148,11 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
40954148
getRepresentation() == SILFunctionTypeRepresentation::Thick;
40964149
}
40974150

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;
40994156

41004157
class ABICompatibilityCheckResult {
41014158
friend class SILFunctionType;
@@ -4139,19 +4196,24 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
41394196
/// assertions are disabled, this just returns true.
41404197
ABICompatibilityCheckResult
41414198
isABICompatibleWith(CanSILFunctionType other,
4142-
SILFunction *context = nullptr) const;
4199+
SILFunction &context) const;
41434200

41444201
CanSILFunctionType substGenericArgs(SILModule &silModule,
41454202
SubstitutionMap subs);
41464203
CanSILFunctionType substGenericArgs(SILModule &silModule,
41474204
TypeSubstitutionFn subs,
41484205
LookupConformanceFn conformances);
41494206

4207+
SILType substInterfaceType(SILModule &M,
4208+
SILType interfaceType) const;
4209+
41504210
void Profile(llvm::FoldingSetNodeID &ID) {
4151-
Profile(ID, getGenericSignature(), getExtInfo(), getCoroutineKind(),
4211+
Profile(ID, getSubstGenericSignature(), getExtInfo(), getCoroutineKind(),
41524212
getCalleeConvention(), getParameters(), getYields(),
41534213
getResults(), getOptionalErrorResult(),
4154-
getWitnessMethodConformanceOrNone());
4214+
getWitnessMethodConformanceOrNone(),
4215+
isGenericSignatureImplied(),
4216+
getSubstitutions());
41554217
}
41564218
static void Profile(llvm::FoldingSetNodeID &ID,
41574219
GenericSignature genericSig,
@@ -4162,7 +4224,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
41624224
ArrayRef<SILYieldInfo> yields,
41634225
ArrayRef<SILResultInfo> results,
41644226
Optional<SILResultInfo> errorResult,
4165-
Optional<ProtocolConformanceRef> conformance);
4227+
Optional<ProtocolConformanceRef> conformance,
4228+
bool isGenericSigImplied,
4229+
SubstitutionMap substitutions);
41664230

41674231
// Implement isa/cast/dyncast/etc.
41684232
static bool classof(const TypeBase *T) {

0 commit comments

Comments
 (0)