Skip to content

Commit 429ae04

Browse files
authored
Merge pull request #6836 from gottesmm/some_more_manage_value_apis
2 parents 162048a + 2c78ca9 commit 429ae04

File tree

1 file changed

+105
-3
lines changed

1 file changed

+105
-3
lines changed

lib/SILGen/ManagedValue.h

Lines changed: 105 additions & 3 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");
@@ -123,7 +210,22 @@ class ManagedValue {
123210
SILValue getValue() const { return valueAndFlag.getPointer(); }
124211

125212
SILType getType() const { return getValue()->getType(); }
126-
213+
214+
/// Transform the given ManagedValue, replacing the underlying value, but
215+
/// keeping the same cleanup.
216+
///
217+
/// For owned values, this is equivalent to forwarding the cleanup and
218+
/// creating a new cleanup of the same type on the new value. This is useful
219+
/// for forwarding sequences.
220+
///
221+
/// For all other values, it is a move.
222+
ManagedValue transform(SILValue newValue) && {
223+
assert(getValue().getOwnershipKind() == newValue.getOwnershipKind() &&
224+
"New value and old value must have the same ownership kind");
225+
ManagedValue M(newValue, isLValue(), getCleanup());
226+
*this = ManagedValue();
227+
return M;
228+
}
127229

128230
CanType getSwiftType() const {
129231
return isLValue()

0 commit comments

Comments
 (0)