mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Allow AbstractionPattern to optionally carry substitutions
This allows the AP to answer questions like how many elements/parameters in the substituted type correspond to this pack expansion. I've threaded this through a lot of cases for foreign patterns that probably won't ever need it.
This commit is contained in:
@@ -425,6 +425,7 @@ class AbstractionPattern {
|
||||
const void *RawTypePtr;
|
||||
};
|
||||
CanGenericSignature GenericSig;
|
||||
SubstitutionMap GenericSubs;
|
||||
|
||||
Kind getKind() const { return Kind(TheKind); }
|
||||
|
||||
@@ -507,45 +508,53 @@ class AbstractionPattern {
|
||||
}
|
||||
}
|
||||
|
||||
void initSwiftType(CanGenericSignature signature, CanType origType,
|
||||
void initSwiftType(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType,
|
||||
Kind kind = Kind::Type) {
|
||||
assert(signature || !origType->hasTypeParameter());
|
||||
TheKind = unsigned(kind);
|
||||
OrigType = origType;
|
||||
GenericSig = CanGenericSignature();
|
||||
GenericSubs = subs;
|
||||
if (OrigType->hasTypeParameter()) {
|
||||
assert(OrigType == signature.getReducedType(origType));
|
||||
GenericSig = signature;
|
||||
}
|
||||
assert(!subs || !OrigType->hasTypeParameter() ||
|
||||
subs.getGenericSignature()->isEqual(
|
||||
getGenericSignatureForFunctionComponent()));
|
||||
}
|
||||
|
||||
void initClangType(CanGenericSignature signature,
|
||||
void initClangType(SubstitutionMap subs, CanGenericSignature signature,
|
||||
CanType origType, const clang::Type *clangType,
|
||||
Kind kind = Kind::ClangType) {
|
||||
initSwiftType(signature, origType, kind);
|
||||
initSwiftType(subs, signature, origType, kind);
|
||||
ClangType = clangType;
|
||||
}
|
||||
|
||||
void initObjCMethod(CanGenericSignature signature,
|
||||
void initObjCMethod(SubstitutionMap subs, CanGenericSignature signature,
|
||||
CanType origType, const clang::ObjCMethodDecl *method,
|
||||
Kind kind, EncodedForeignInfo errorInfo) {
|
||||
initSwiftType(signature, origType, kind);
|
||||
initSwiftType(subs, signature, origType, kind);
|
||||
ObjCMethod = method;
|
||||
OtherData = errorInfo.getOpaqueValue();
|
||||
}
|
||||
|
||||
void initCFunctionAsMethod(CanGenericSignature signature,
|
||||
void initCFunctionAsMethod(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType, const clang::Type *clangType,
|
||||
Kind kind,
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
initClangType(signature, origType, clangType, kind);
|
||||
initClangType(subs, signature, origType, clangType, kind);
|
||||
OtherData = memberStatus.getRawValue();
|
||||
}
|
||||
|
||||
void initCXXMethod(CanGenericSignature signature, CanType origType,
|
||||
void initCXXMethod(SubstitutionMap subs,
|
||||
CanGenericSignature signature, CanType origType,
|
||||
const clang::CXXMethodDecl *method, Kind kind,
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
initSwiftType(signature, origType, kind);
|
||||
initSwiftType(subs, signature, origType, kind);
|
||||
CXXMethod = method;
|
||||
OtherData = memberStatus.getRawValue();
|
||||
}
|
||||
@@ -559,13 +568,27 @@ public:
|
||||
explicit AbstractionPattern(CanType origType)
|
||||
: AbstractionPattern(nullptr, origType) {}
|
||||
explicit AbstractionPattern(CanGenericSignature signature, CanType origType) {
|
||||
initSwiftType(signature, origType);
|
||||
initSwiftType(SubstitutionMap(), signature, origType);
|
||||
}
|
||||
explicit AbstractionPattern(SubstitutionMap subs, CanType origType) {
|
||||
initSwiftType(subs, subs.getGenericSignature().getCanonicalSignature(),
|
||||
origType);
|
||||
}
|
||||
explicit AbstractionPattern(SubstitutionMap subs, CanGenericSignature sig,
|
||||
CanType origType) {
|
||||
initSwiftType(subs, sig, origType);
|
||||
}
|
||||
explicit AbstractionPattern(CanType origType, const clang::Type *clangType)
|
||||
: AbstractionPattern(nullptr, origType, clangType) {}
|
||||
explicit AbstractionPattern(CanGenericSignature signature, CanType origType,
|
||||
const clang::Type *clangType) {
|
||||
initClangType(signature, origType, clangType);
|
||||
initClangType(SubstitutionMap(), signature, origType, clangType);
|
||||
}
|
||||
explicit AbstractionPattern(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType,
|
||||
const clang::Type *clangType) {
|
||||
initClangType(subs, signature, origType, clangType);
|
||||
}
|
||||
|
||||
static AbstractionPattern getOpaque() {
|
||||
@@ -610,6 +633,10 @@ public:
|
||||
llvm_unreachable("Unhandled AbstractionPatternKind in switch");
|
||||
}
|
||||
|
||||
SubstitutionMap getGenericSubstitutions() const {
|
||||
return GenericSubs;
|
||||
}
|
||||
|
||||
CanGenericSignature getGenericSignature() const {
|
||||
assert(hasGenericSignature());
|
||||
return CanGenericSignature(GenericSig);
|
||||
@@ -635,12 +662,13 @@ public:
|
||||
/// corresponding to the parameters of a completion handler
|
||||
/// block of an API that was imported as async.
|
||||
static AbstractionPattern
|
||||
getObjCCompletionHandlerArgumentsType(CanGenericSignature sig,
|
||||
getObjCCompletionHandlerArgumentsType(SubstitutionMap subs,
|
||||
CanGenericSignature sig,
|
||||
CanType origTupleType,
|
||||
const clang::Type *clangBlockType,
|
||||
EncodedForeignInfo foreignInfo) {
|
||||
AbstractionPattern pattern(Kind::ObjCCompletionHandlerArgumentsType);
|
||||
pattern.initClangType(sig, origTupleType, clangBlockType,
|
||||
pattern.initClangType(subs, sig, origTupleType, clangBlockType,
|
||||
Kind::ObjCCompletionHandlerArgumentsType);
|
||||
pattern.OtherData = foreignInfo.getOpaqueValue();
|
||||
|
||||
@@ -670,7 +698,8 @@ public:
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCFunctionAsMethod(nullptr, origType, clangType,
|
||||
pattern.initCFunctionAsMethod(SubstitutionMap(), nullptr,
|
||||
origType, clangType,
|
||||
Kind::CFunctionAsMethodType,
|
||||
memberStatus);
|
||||
return pattern;
|
||||
@@ -705,7 +734,7 @@ public:
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCXXMethod(nullptr, origType, method,
|
||||
pattern.initCXXMethod(SubstitutionMap(), nullptr, origType, method,
|
||||
Kind::CXXMethodType, memberStatus);
|
||||
return pattern;
|
||||
}
|
||||
@@ -722,7 +751,7 @@ public:
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCXXMethod(nullptr, origType, method,
|
||||
pattern.initCXXMethod(SubstitutionMap(), nullptr, origType, method,
|
||||
Kind::CurriedCXXMethodType, memberStatus);
|
||||
return pattern;
|
||||
}
|
||||
@@ -738,10 +767,11 @@ public:
|
||||
|
||||
/// Return an abstraction pattern for a value that is discarded after being
|
||||
/// evaluated.
|
||||
static AbstractionPattern
|
||||
getDiscard(CanGenericSignature signature, CanType origType) {
|
||||
static AbstractionPattern getDiscard(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType) {
|
||||
AbstractionPattern pattern;
|
||||
pattern.initSwiftType(signature, origType, Kind::Discard);
|
||||
pattern.initSwiftType(subs, signature, origType, Kind::Discard);
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@@ -761,7 +791,7 @@ private:
|
||||
EncodedForeignInfo errorInfo) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initObjCMethod(nullptr, origType, method,
|
||||
pattern.initObjCMethod(SubstitutionMap(), nullptr, origType, method,
|
||||
Kind::CurriedObjCMethodType, errorInfo);
|
||||
return pattern;
|
||||
}
|
||||
@@ -772,7 +802,8 @@ private:
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCFunctionAsMethod(nullptr, origType, clangType,
|
||||
pattern.initCFunctionAsMethod(SubstitutionMap(), nullptr,
|
||||
origType, clangType,
|
||||
Kind::CurriedCFunctionAsMethodType,
|
||||
memberStatus);
|
||||
return pattern;
|
||||
@@ -781,13 +812,14 @@ private:
|
||||
/// Return an abstraction pattern for the partially-applied curried
|
||||
/// type of an Objective-C method.
|
||||
static AbstractionPattern
|
||||
getPartialCurriedObjCMethod(CanGenericSignature signature,
|
||||
getPartialCurriedObjCMethod(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType,
|
||||
const clang::ObjCMethodDecl *method,
|
||||
EncodedForeignInfo errorInfo) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initObjCMethod(signature, origType, method,
|
||||
pattern.initObjCMethod(subs, signature, origType, method,
|
||||
Kind::PartialCurriedObjCMethodType, errorInfo);
|
||||
return pattern;
|
||||
}
|
||||
@@ -802,13 +834,14 @@ private:
|
||||
/// and the partially-applied curried type is:
|
||||
/// (CCTemperature) -> ()
|
||||
static AbstractionPattern
|
||||
getPartialCurriedCFunctionAsMethod(CanGenericSignature signature,
|
||||
getPartialCurriedCFunctionAsMethod(SubstitutionMap subs,
|
||||
CanGenericSignature signature,
|
||||
CanType origType,
|
||||
const clang::Type *clangType,
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCFunctionAsMethod(signature, origType, clangType,
|
||||
pattern.initCFunctionAsMethod(subs, signature, origType, clangType,
|
||||
Kind::PartialCurriedCFunctionAsMethodType,
|
||||
memberStatus);
|
||||
return pattern;
|
||||
@@ -823,12 +856,13 @@ private:
|
||||
/// then the partially-applied curried type is:
|
||||
/// (Compartment, Temperature) -> ()
|
||||
static AbstractionPattern
|
||||
getPartialCurriedCXXMethod(CanGenericSignature signature, CanType origType,
|
||||
getPartialCurriedCXXMethod(SubstitutionMap subs,
|
||||
CanGenericSignature signature, CanType origType,
|
||||
const clang::CXXMethodDecl *method,
|
||||
ImportAsMemberStatus memberStatus) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initCXXMethod(signature, origType, method,
|
||||
pattern.initCXXMethod(subs, signature, origType, method,
|
||||
Kind::PartialCurriedCXXMethodType, memberStatus);
|
||||
return pattern;
|
||||
}
|
||||
@@ -848,7 +882,8 @@ private:
|
||||
EncodedForeignInfo errorInfo) {
|
||||
assert(isa<AnyFunctionType>(origType));
|
||||
AbstractionPattern pattern;
|
||||
pattern.initObjCMethod(nullptr, origType, method, Kind::ObjCMethodType,
|
||||
pattern.initObjCMethod(SubstitutionMap(), nullptr,
|
||||
origType, method, Kind::ObjCMethodType,
|
||||
errorInfo);
|
||||
return pattern;
|
||||
}
|
||||
@@ -947,7 +982,17 @@ public:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isPackExpansion() const {
|
||||
switch (getKind()) {
|
||||
case Kind::Type:
|
||||
case Kind::Discard:
|
||||
return isa<PackExpansionType>(getType());
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this an interface type that is subject to a concrete
|
||||
/// same-type constraint?
|
||||
bool isConcreteType() const;
|
||||
@@ -1032,6 +1077,24 @@ public:
|
||||
llvm_unreachable("bad kind");
|
||||
}
|
||||
|
||||
/// Add substitutions to this pattern.
|
||||
AbstractionPattern withSubstitutions(SubstitutionMap subs) const {
|
||||
AbstractionPattern result = *this;
|
||||
if (subs) {
|
||||
#ifndef NDEBUG
|
||||
// If we have a generic signature, it should match the substitutions.
|
||||
// But there are situations in which it's okay that we don't store
|
||||
// a signature.
|
||||
auto sig = getGenericSignatureForFunctionComponent();
|
||||
assert((sig && sig->isEqual(subs.getGenericSignature())) ||
|
||||
!OrigType ||
|
||||
!OrigType->hasTypeParameter());
|
||||
#endif
|
||||
result.GenericSubs = subs;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return whether this abstraction pattern contains foreign type
|
||||
/// information.
|
||||
///
|
||||
@@ -1359,8 +1422,14 @@ public:
|
||||
/// the abstraction pattern for one of its parameter types.
|
||||
AbstractionPattern getFunctionParamType(unsigned index) const;
|
||||
|
||||
/// Given that the value being abstracted is a function type, return
|
||||
/// the number of parameters.
|
||||
/// Given that the value being abstracted is a function type, and that
|
||||
/// this is not an opaque abstraction pattern, return the parameter flags
|
||||
/// for one of its parameters.
|
||||
ParameterTypeFlags getFunctionParamFlags(unsigned index) const;
|
||||
|
||||
/// Given that the value being abstracted is a function type, and that
|
||||
/// this is not an opaque abstraction pattern, return the number of
|
||||
/// parameters in the pattern.
|
||||
unsigned getNumFunctionParams() const;
|
||||
|
||||
/// Given that the value being abstracted is optional, return the
|
||||
@@ -1394,13 +1463,22 @@ public:
|
||||
AbstractionPattern getObjCMethodAsyncCompletionHandlerType(
|
||||
CanType swiftCompletionHandlerType) const;
|
||||
|
||||
/// Given that this is a pack expansion, invoke the given callback for
|
||||
/// each component of the substituted expansion of this pattern. The
|
||||
/// pattern will be for a pack expansion type over a contextual type if
|
||||
/// the substituted component is still a pack expansion. If there aren't
|
||||
/// substitutions available, this will just invoke the callback with the
|
||||
/// component.
|
||||
void forEachPackExpandedComponent(
|
||||
llvm::function_ref<void(AbstractionPattern pattern)> fn) const;
|
||||
|
||||
/// If this pattern refers to a foreign ObjC method that was imported as
|
||||
/// async, return the bridged-back-to-ObjC completion handler type.
|
||||
CanType getObjCMethodAsyncCompletionHandlerForeignType(
|
||||
ForeignAsyncConvention convention,
|
||||
Lowering::TypeConverter &TC
|
||||
) const;
|
||||
|
||||
|
||||
/// How values are passed or returned according to this abstraction pattern.
|
||||
enum CallingConventionKind {
|
||||
// Value is passed or returned directly as a unit.
|
||||
|
||||
Reference in New Issue
Block a user