mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #73348 from slavapestov/pack-expansion-closures-part-1
Preliminary steps towards support for closures that capture pack element environments
This commit is contained in:
@@ -75,13 +75,6 @@ public:
|
||||
return TheFunction.get<AbstractClosureExpr *>()->getCaptureInfo();
|
||||
}
|
||||
|
||||
|
||||
bool hasType() const {
|
||||
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
|
||||
return AFD->hasInterfaceType();
|
||||
return !TheFunction.get<AbstractClosureExpr *>()->getType().isNull();
|
||||
}
|
||||
|
||||
ParameterList *getParameters() const {
|
||||
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
|
||||
return AFD->getParameters();
|
||||
@@ -174,20 +167,8 @@ public:
|
||||
return TheFunction.dyn_cast<AbstractClosureExpr*>();
|
||||
}
|
||||
|
||||
/// Return true if this closure is passed as an argument to a function and is
|
||||
/// known not to escape from that function. In this case, captures can be
|
||||
/// more efficient.
|
||||
bool isKnownNoEscape() const {
|
||||
if (hasType() && !getType()->hasError())
|
||||
return getType()->castTo<AnyFunctionType>()->isNoEscape();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Whether this function is @Sendable.
|
||||
bool isSendable() const {
|
||||
if (!hasType())
|
||||
return false;
|
||||
|
||||
if (auto *fnType = getType()->getAs<AnyFunctionType>())
|
||||
return fnType->isSendable();
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class ValueDecl;
|
||||
class FuncDecl;
|
||||
class OpaqueValueExpr;
|
||||
class VarDecl;
|
||||
class GenericEnvironment;
|
||||
|
||||
/// CapturedValue includes both the declaration being captured, along with flags
|
||||
/// that indicate how it is captured.
|
||||
@@ -140,19 +141,27 @@ class DynamicSelfType;
|
||||
/// Stores information about captured variables.
|
||||
class CaptureInfo {
|
||||
class CaptureInfoStorage final
|
||||
: public llvm::TrailingObjects<CaptureInfoStorage, CapturedValue> {
|
||||
: public llvm::TrailingObjects<CaptureInfoStorage,
|
||||
CapturedValue,
|
||||
GenericEnvironment *> {
|
||||
|
||||
DynamicSelfType *DynamicSelf;
|
||||
OpaqueValueExpr *OpaqueValue;
|
||||
unsigned Count;
|
||||
public:
|
||||
explicit CaptureInfoStorage(unsigned count, DynamicSelfType *dynamicSelf,
|
||||
OpaqueValueExpr *opaqueValue)
|
||||
: DynamicSelf(dynamicSelf), OpaqueValue(opaqueValue), Count(count) { }
|
||||
unsigned NumCapturedValues;
|
||||
unsigned NumGenericEnvironments;
|
||||
|
||||
ArrayRef<CapturedValue> getCaptures() const {
|
||||
return llvm::ArrayRef(this->getTrailingObjects<CapturedValue>(), Count);
|
||||
}
|
||||
public:
|
||||
explicit CaptureInfoStorage(DynamicSelfType *dynamicSelf,
|
||||
OpaqueValueExpr *opaqueValue,
|
||||
unsigned numCapturedValues,
|
||||
unsigned numGenericEnvironments)
|
||||
: DynamicSelf(dynamicSelf), OpaqueValue(opaqueValue),
|
||||
NumCapturedValues(numCapturedValues),
|
||||
NumGenericEnvironments(numGenericEnvironments) { }
|
||||
|
||||
ArrayRef<CapturedValue> getCaptures() const;
|
||||
|
||||
ArrayRef<GenericEnvironment *> getGenericEnvironments() const;
|
||||
|
||||
DynamicSelfType *getDynamicSelfType() const {
|
||||
return DynamicSelf;
|
||||
@@ -161,6 +170,10 @@ class CaptureInfo {
|
||||
OpaqueValueExpr *getOpaqueValue() const {
|
||||
return OpaqueValue;
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<CapturedValue>) const {
|
||||
return NumCapturedValues;
|
||||
}
|
||||
};
|
||||
|
||||
enum class Flags : unsigned {
|
||||
@@ -173,9 +186,11 @@ class CaptureInfo {
|
||||
public:
|
||||
/// The default-constructed CaptureInfo is "not yet computed".
|
||||
CaptureInfo() = default;
|
||||
CaptureInfo(ASTContext &ctx, ArrayRef<CapturedValue> captures,
|
||||
CaptureInfo(ASTContext &ctx,
|
||||
ArrayRef<CapturedValue> captures,
|
||||
DynamicSelfType *dynamicSelf, OpaqueValueExpr *opaqueValue,
|
||||
bool genericParamCaptures);
|
||||
bool genericParamCaptures,
|
||||
ArrayRef<GenericEnvironment *> genericEnv=ArrayRef<GenericEnvironment*>());
|
||||
|
||||
/// A CaptureInfo representing no captures at all.
|
||||
static CaptureInfo empty();
|
||||
@@ -190,12 +205,20 @@ public:
|
||||
!hasDynamicSelfCapture() && !hasOpaqueValueCapture();
|
||||
}
|
||||
|
||||
/// Returns all captured values and opaque expressions.
|
||||
ArrayRef<CapturedValue> getCaptures() const {
|
||||
assert(hasBeenComputed());
|
||||
return StorageAndFlags.getPointer()->getCaptures();
|
||||
}
|
||||
|
||||
/// \returns true if the function captures any generic type parameters.
|
||||
/// Returns all captured pack element environments.
|
||||
ArrayRef<GenericEnvironment *> getGenericEnvironments() const {
|
||||
assert(hasBeenComputed());
|
||||
return StorageAndFlags.getPointer()->getGenericEnvironments();
|
||||
}
|
||||
|
||||
/// \returns true if the function captures the primary generic environment
|
||||
/// from its innermost declaration context.
|
||||
bool hasGenericParamCaptures() const {
|
||||
assert(hasBeenComputed());
|
||||
return StorageAndFlags.getInt().contains(Flags::HasGenericParamCaptures);
|
||||
|
||||
Reference in New Issue
Block a user