Skip to content

Commit d24bc38

Browse files
authored
Merge pull request swiftlang#23701 from DougGregor/property-delegates-as-custom-attributes
2 parents 9b2db03 + 0c26e43 commit d24bc38

File tree

94 files changed

+4395
-188
lines changed

Some content is hidden

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

94 files changed

+4395
-188
lines changed

docs/SIL.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,32 @@ with a sequence that also correctly destroys the current value.
23332333
This instruction is only valid in Raw SIL and is rewritten as appropriate
23342334
by the definitive initialization pass.
23352335

2336+
assign_by_delegate
2337+
``````````````````
2338+
::
2339+
2340+
sil-instruction ::= 'assign_by_delegate' sil-operand 'to' sil-operand ',' 'init' sil-operand ',' 'set' sil-operand
2341+
2342+
assign_by_delegate %0 : $S to %1 : $*T, init %2 : $F, set %3 : $G
2343+
// $S can be a value or address type
2344+
// $T must be the type of a property delegate.
2345+
// $F must be a function type, taking $S as a single argument and returning $T
2346+
// $G must be a function type, taking $S as a single argument and with not return value
2347+
2348+
Similar to the ``assign`` instruction, but the assignment is done via a
2349+
delegate.
2350+
2351+
In case of an initialization, the function ``%2`` is called with ``%0`` as
2352+
argument. The result is stored to ``%1``. In case ``%2`` is an address type,
2353+
it is simply passed as a first out-argument to ``%2``.
2354+
2355+
In case of a re-assignment, the function ``%3`` is called with ``%0`` as
2356+
argument. As ``%3`` is a setter (e.g. for the property in the containing
2357+
nominal type), the destination address ``%1`` is not used in this case.
2358+
2359+
This instruction is only valid in Raw SIL and is rewritten as appropriate
2360+
by the definitive initialization pass.
2361+
23362362
mark_uninitialized
23372363
``````````````````
23382364
::

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,13 @@ class ASTContext final {
833833
const IterableDeclContext *idc,
834834
LazyMemberLoader *lazyLoader);
835835

836+
/// Access the side cache for property delegate backing property types,
837+
/// used because TypeChecker::typeCheckBinding() needs somewhere to stash
838+
/// the backing property type.
839+
Type getSideCachedPropertyDelegateBackingPropertyType(VarDecl *var) const;
840+
void setSideCachedPropertyDelegateBackingPropertyType(VarDecl *var,
841+
Type type);
842+
836843
/// Returns memory usage of this ASTContext.
837844
size_t getTotalMemory() const;
838845

include/swift/AST/ASTTypeIDZone.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@
1616
//===----------------------------------------------------------------------===//
1717
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
1818
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
19-
SWIFT_TYPEID(PropertyBehaviorTypeInfo)
19+
SWIFT_TYPEID(Type)
20+
SWIFT_TYPEID(PropertyDelegateBackingPropertyInfo)
21+
SWIFT_TYPEID(PropertyDelegateTypeInfo)
22+
SWIFT_TYPEID_NAMED(CustomAttr *, CustomAttr)

include/swift/AST/ASTTypeIDs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
#include "swift/Basic/TypeID.h"
2121
namespace swift {
2222

23+
class CustomAttr;
2324
class NominalTypeDecl;
24-
struct PropertyBehaviorTypeInfo;
25+
struct PropertyDelegateBackingPropertyInfo;
26+
struct PropertyDelegateTypeInfo;
27+
class Type;
2528
class VarDecl;
2629

2730
#define SWIFT_AST_TYPEID_ZONE 1

include/swift/AST/Attr.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
399399
DECL_ATTR(_custom, Custom,
400400
OnAnyDecl | UserInaccessible,
401401
85)
402+
SIMPLE_DECL_ATTR(_propertyDelegate, PropertyDelegate,
403+
OnStruct | OnClass | OnEnum,
404+
86)
402405

403406
#undef TYPE_ATTR
404407
#undef DECL_ATTR_ALIAS

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,7 @@ class CustomAttr final : public DeclAttribute,
14281428
TypeLoc type;
14291429
Expr *arg;
14301430
PatternBindingInitializer *initContext;
1431+
Expr *semanticInit = nullptr;
14311432

14321433
unsigned hasArgLabelLocs : 1;
14331434
unsigned numArgLabels : 16;
@@ -1463,6 +1464,9 @@ class CustomAttr final : public DeclAttribute,
14631464
Expr *getArg() const { return arg; }
14641465
void setArg(Expr *newArg) { arg = newArg; }
14651466

1467+
Expr *getSemanticInit() const { return semanticInit; }
1468+
void setSemanticInit(Expr *expr) { semanticInit = expr; }
1469+
14661470
PatternBindingInitializer *getInitContext() const { return initContext; }
14671471

14681472
static bool classof(const DeclAttribute *DA) {

include/swift/AST/CaptureInfo.h

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/TypeAlignments.h"
1818
#include "llvm/ADT/ArrayRef.h"
1919
#include "llvm/ADT/PointerIntPair.h"
20+
#include "llvm/ADT/PointerUnion.h"
2021
#include <vector>
2122

2223
namespace swift {
@@ -31,13 +32,20 @@ template <> struct DenseMapInfo<swift::CapturedValue>;
3132
namespace swift {
3233
class ValueDecl;
3334
class FuncDecl;
35+
class OpaqueValueExpr;
3436

3537
/// CapturedValue includes both the declaration being captured, along with flags
3638
/// that indicate how it is captured.
3739
class CapturedValue {
38-
llvm::PointerIntPair<ValueDecl*, 2, unsigned> Value;
40+
public:
41+
using Storage =
42+
llvm::PointerIntPair<llvm::PointerUnion<ValueDecl*, OpaqueValueExpr*>, 2,
43+
unsigned>;
44+
45+
private:
46+
Storage Value;
3947

40-
explicit CapturedValue(llvm::PointerIntPair<ValueDecl*, 2, unsigned> V) : Value(V) {}
48+
explicit CapturedValue(Storage V) : Value(V) {}
4149

4250
public:
4351
friend struct llvm::DenseMapInfo<CapturedValue>;
@@ -53,16 +61,21 @@ class CapturedValue {
5361
IsNoEscape = 1 << 1
5462
};
5563

56-
CapturedValue(ValueDecl *D, unsigned Flags) : Value(D, Flags) {}
64+
CapturedValue(llvm::PointerUnion<ValueDecl*, OpaqueValueExpr*> Ptr,
65+
unsigned Flags)
66+
: Value(Ptr, Flags) {}
5767

5868
static CapturedValue getDynamicSelfMetadata() {
59-
return CapturedValue(nullptr, 0);
69+
return CapturedValue((ValueDecl *)nullptr, 0);
6070
}
6171

6272
bool isDirect() const { return Value.getInt() & IsDirect; }
6373
bool isNoEscape() const { return Value.getInt() & IsNoEscape; }
6474

6575
bool isDynamicSelfMetadata() const { return !Value.getPointer(); }
76+
bool isOpaqueValue() const {
77+
return Value.getPointer().is<OpaqueValueExpr *>();
78+
}
6679

6780
CapturedValue mergeFlags(CapturedValue cv) {
6881
assert(Value.getPointer() == cv.Value.getPointer() &&
@@ -73,7 +86,13 @@ class CapturedValue {
7386
ValueDecl *getDecl() const {
7487
assert(Value.getPointer() && "dynamic Self metadata capture does not "
7588
"have a value");
76-
return Value.getPointer();
89+
return Value.getPointer().dyn_cast<ValueDecl *>();
90+
}
91+
92+
OpaqueValueExpr *getOpaqueValue() const {
93+
assert(Value.getPointer() && "dynamic Self metadata capture does not "
94+
"have a value");
95+
return Value.getPointer().dyn_cast<OpaqueValueExpr *>();
7796
}
7897

7998
unsigned getFlags() const { return Value.getInt(); }
@@ -98,8 +117,7 @@ namespace llvm {
98117
template <> struct DenseMapInfo<swift::CapturedValue> {
99118
using CapturedValue = swift::CapturedValue;
100119

101-
using PtrIntPairDenseMapInfo =
102-
DenseMapInfo<llvm::PointerIntPair<swift::ValueDecl *, 2, unsigned>>;
120+
using PtrIntPairDenseMapInfo = DenseMapInfo<CapturedValue::Storage>;
103121

104122
static inline swift::CapturedValue getEmptyKey() {
105123
return CapturedValue{PtrIntPairDenseMapInfo::getEmptyKey()};
@@ -128,19 +146,20 @@ class DynamicSelfType;
128146
class CaptureInfo {
129147
const CapturedValue *Captures;
130148
DynamicSelfType *DynamicSelf;
149+
OpaqueValueExpr *OpaqueValue;
131150
unsigned Count = 0;
132151
bool GenericParamCaptures : 1;
133152
bool Computed : 1;
134153

135154
public:
136155
CaptureInfo()
137-
: Captures(nullptr), DynamicSelf(nullptr), Count(0),
156+
: Captures(nullptr), DynamicSelf(nullptr), OpaqueValue(nullptr), Count(0),
138157
GenericParamCaptures(0), Computed(0) { }
139158

140159
bool hasBeenComputed() { return Computed; }
141160

142161
bool isTrivial() {
143-
return Count == 0 && !GenericParamCaptures && !DynamicSelf;
162+
return Count == 0 && !GenericParamCaptures && !DynamicSelf && !OpaqueValue;
144163
}
145164

146165
ArrayRef<CapturedValue> getCaptures() const {
@@ -184,6 +203,18 @@ class CaptureInfo {
184203
DynamicSelf = dynamicSelf;
185204
}
186205

206+
bool hasOpaqueValueCapture() const {
207+
return OpaqueValue != nullptr;
208+
}
209+
210+
OpaqueValueExpr *getOpaqueValue() const {
211+
return OpaqueValue;
212+
}
213+
214+
void setOpaqueValue(OpaqueValueExpr *OVE) {
215+
OpaqueValue = OVE;
216+
}
217+
187218
void dump() const;
188219
void print(raw_ostream &OS) const;
189220
};

0 commit comments

Comments
 (0)