Skip to content

Commit 2c78ca9

Browse files
committed
[semantic-sil] Introduce new specific static constructors for ManagedValue.
This is the first step towards eliminating: * ManagedValue::forUnmanaged(SILValue) * ManagedValue::ManagedValue(SILValue, CleanupHandle). The reason why these two methods must be eliminated is that: 1. Currently non-trivial values are "borrowed" using ManagedValue::forUnmanaged. With Semantic SIL, we are now able to represent borrows via begin_borrow and end_borrow. This will make the semantics that SILGen is trying to describe more accurate. 2. ManagedValue::ManagedValue can be used to add arbitrary cleanups. We want methods that add cleanups, but that at the same time allow the caller to specify what it expects the ownership of the given SILValue to be. This would then cause an assertion to trip giving greater clarity. rdar://29791263
1 parent 3985a11 commit 2c78ca9

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

lib/SILGen/ManagedValue.h

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,106 @@ class ManagedValue {
6666
public:
6767

6868
ManagedValue() = default;
69-
69+
7070
/// Create a managed value for a +1 rvalue.
71+
///
72+
/// Please do not introduce new uses of this method! Instead use one of the
73+
/// static constructors below.
7174
ManagedValue(SILValue value, CleanupHandle cleanup)
7275
: valueAndFlag(value, false), cleanup(cleanup) {
73-
assert(value && "No value specified");
76+
assert(value && "No value specified?!");
7477
}
7578

7679
/// Create a managed value for a +0 rvalue.
80+
///
81+
/// Please do not introduce new uses of this method! Instead use one of the
82+
/// static constructors below!
7783
static ManagedValue forUnmanaged(SILValue value) {
7884
assert(value && "No value specified");
7985
return ManagedValue(value, false, CleanupHandle::invalid());
8086
}
8187

88+
/// Create a managed value for a +1 rvalue object.
89+
static ManagedValue forOwnedObjectRValue(SILValue value,
90+
CleanupHandle cleanup) {
91+
assert(value && "No value specified");
92+
assert(value->getType().isObject() &&
93+
"Expected borrowed rvalues to be objects");
94+
assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
95+
return ManagedValue(value, false, cleanup);
96+
}
97+
98+
/// Create a managed value for a +1 rvalue address.
99+
///
100+
/// From a high level perspective, this consists of a temporary buffer.
101+
static ManagedValue forOwnedAddressRValue(SILValue value,
102+
CleanupHandle cleanup) {
103+
assert(value && "No value specified");
104+
assert(value->getType().isAddress() && "Expected value to be an address");
105+
assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
106+
"Addresses always have trivial ownership");
107+
return ManagedValue(value, false, cleanup);
108+
}
109+
110+
/// Create a managed value for a +1 non-trivial rvalue.
111+
static ManagedValue forOwnedRValue(SILValue value, CleanupHandle cleanup) {
112+
if (value->getType().isAddress())
113+
return ManagedValue::forOwnedAddressRValue(value, cleanup);
114+
return ManagedValue::forOwnedObjectRValue(value, cleanup);
115+
}
116+
117+
/// Create a managed value for a +0 borrowed non-trivial rvalue object.
118+
static ManagedValue
119+
forBorrowedObjectRValue(SILValue value,
120+
CleanupHandle cleanup = CleanupHandle::invalid()) {
121+
assert(value && "No value specified");
122+
assert(value->getType().isObject() &&
123+
"Expected borrowed rvalues to be objects");
124+
assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
125+
return ManagedValue(value, false, cleanup);
126+
}
127+
128+
/// Create a managed value for a +0 borrowed non-trivial rvalue address.
129+
static ManagedValue
130+
forBorrowedAddressRValue(SILValue value,
131+
CleanupHandle cleanup = CleanupHandle::invalid()) {
132+
assert(value && "No value specified");
133+
assert(value->getType().isAddress() && "Expected value to be an address");
134+
assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
135+
"Addresses always have trivial ownership");
136+
return ManagedValue(value, false, cleanup);
137+
}
138+
139+
/// Create a managed value for a +0 guaranteed rvalue.
140+
static ManagedValue
141+
forBorrowedRValue(SILValue value,
142+
CleanupHandle cleanup = CleanupHandle::invalid()) {
143+
if (value->getType().isAddress())
144+
return ManagedValue::forBorrowedAddressRValue(value, cleanup);
145+
return ManagedValue::forBorrowedObjectRValue(value, cleanup);
146+
}
147+
148+
/// Create a managed value for a +0 trivial object rvalue.
149+
static ManagedValue forTrivialObjectRValue(SILValue value) {
150+
assert(value->getType().isObject() && "Expected an object");
151+
assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial);
152+
return ManagedValue(value, false, CleanupHandle::invalid());
153+
}
154+
155+
/// Create a managed value for a +0 trivial address rvalue.
156+
static ManagedValue forTrivialAddressRValue(SILValue value) {
157+
assert(value->getType().isAddress() && "Expected an address");
158+
assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial);
159+
return ManagedValue(value, false, CleanupHandle::invalid());
160+
}
161+
162+
/// Create a managed value for a +0 trivial rvalue.
163+
static ManagedValue forTrivialRValue(SILValue value) {
164+
if (value->getType().isObject())
165+
return ManagedValue::forTrivialObjectRValue(value);
166+
return ManagedValue::forTrivialAddressRValue(value);
167+
}
168+
82169
/// Create a managed value for an l-value.
83170
static ManagedValue forLValue(SILValue value) {
84171
assert(value && "No value specified");

0 commit comments

Comments
 (0)