Skip to content

Commit 12871d7

Browse files
committed
[AST] Introduce "ValueOwnership" collecting __shared, inout, etc.
This is designed to stop having to n bits to track each of the mutually exclusive 'shared', 'inout' and eventually 'owned'.
1 parent b94c536 commit 12871d7

File tree

10 files changed

+148
-51
lines changed

10 files changed

+148
-51
lines changed

include/swift/AST/Decl.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4594,7 +4594,20 @@ class VarDecl : public AbstractStorageDecl {
45944594
bool isLet() const { return getSpecifier() == Specifier::Let; }
45954595
/// Is this an immutable 'shared' property?
45964596
bool isShared() const { return getSpecifier() == Specifier::Shared; }
4597-
4597+
4598+
ValueOwnership getValueOwnership() const {
4599+
switch (getSpecifier()) {
4600+
case Specifier::Let:
4601+
return ValueOwnership::Default;
4602+
case Specifier::Var:
4603+
return ValueOwnership::Default;
4604+
case Specifier::InOut:
4605+
return ValueOwnership::InOut;
4606+
case Specifier::Shared:
4607+
return ValueOwnership::Shared;
4608+
}
4609+
}
4610+
45984611
/// Is this an element in a capture list?
45994612
bool isCaptureList() const { return Bits.VarDecl.IsCaptureList; }
46004613

include/swift/AST/Ownership.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- Ownership.h - Swift ASTs for Reference Ownership -------*- C++ -*-===//
1+
//===--- Ownership.h - Swift ASTs for Ownership ---------------*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,9 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file defines common structures for working with the different
14-
// kinds of reference ownership supported by Swift, such as 'weak' and
15-
// 'unowned'.
13+
// This file defines common structures for working with the different kinds of
14+
// reference ownership supported by Swift, such as 'weak' and 'unowned', as well
15+
// as the different kinds of value ownership, such as 'inout' and '__shared'.
1616
//
1717
//===----------------------------------------------------------------------===//
1818

@@ -40,6 +40,16 @@ enum class ReferenceOwnership : uint8_t {
4040
Unmanaged,
4141
};
4242

43+
/// Different kinds of value ownership supported by Swift.
44+
enum class ValueOwnership : uint8_t {
45+
/// \brief the default ownership (owned)
46+
Default,
47+
/// \brief an 'inout' mutating pointer-like value
48+
InOut,
49+
/// \brief a '__shared' non-mutating pointer-like value
50+
Shared
51+
};
52+
4353
} // end namespace swift
4454

4555
#endif

include/swift/AST/Types.h

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,17 +1594,16 @@ class ParameterTypeFlags {
15941594
return ParameterTypeFlags(OptionSet<ParameterFlags>(raw));
15951595
}
15961596

1597-
ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping, bool inOut, bool shared)
1598-
: value((variadic ? Variadic : 0) |
1599-
(autoclosure ? AutoClosure : 0) |
1597+
ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping,
1598+
ValueOwnership ownership)
1599+
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
16001600
(escaping ? Escaping : 0) |
1601-
(inOut ? InOut : 0) |
1602-
(shared ? Shared : 0)) {}
1601+
(ownership == ValueOwnership::InOut ? InOut : 0) |
1602+
(ownership == ValueOwnership::Shared ? Shared : 0)) {}
16031603

16041604
/// Create one from what's present in the parameter type
1605-
inline static ParameterTypeFlags fromParameterType(Type paramTy,
1606-
bool isVariadic,
1607-
bool isShared);
1605+
inline static ParameterTypeFlags
1606+
fromParameterType(Type paramTy, bool isVariadic, ValueOwnership ownership);
16081607

16091608
bool isNone() const { return !value; }
16101609
bool isVariadic() const { return value.contains(Variadic); }
@@ -1613,6 +1612,15 @@ class ParameterTypeFlags {
16131612
bool isInOut() const { return value.contains(InOut); }
16141613
bool isShared() const { return value.contains(Shared); }
16151614

1615+
ValueOwnership getValueOwnership() const {
1616+
if (isInOut())
1617+
return ValueOwnership::InOut;
1618+
else if (isShared())
1619+
return ValueOwnership::Shared;
1620+
1621+
return ValueOwnership::Default;
1622+
}
1623+
16161624
ParameterTypeFlags withVariadic(bool variadic) const {
16171625
return ParameterTypeFlags(variadic ? value | ParameterTypeFlags::Variadic
16181626
: value - ParameterTypeFlags::Variadic);
@@ -5168,7 +5176,8 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
51685176

51695177
/// Create one from what's present in the parameter decl and type
51705178
inline ParameterTypeFlags
5171-
ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic, bool isShared) {
5179+
ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic,
5180+
ValueOwnership ownership) {
51725181
bool autoclosure = paramTy->is<AnyFunctionType>() &&
51735182
paramTy->castTo<AnyFunctionType>()->isAutoClosure();
51745183
bool escaping = paramTy->is<AnyFunctionType>() &&
@@ -5177,8 +5186,12 @@ ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic, bool isShar
51775186
// decomposition. Start by enabling the assertion there and fixing up those
51785187
// callers, then remove this, then remove
51795188
// ParameterTypeFlags::fromParameterType entirely.
5180-
bool inOut = paramTy->is<InOutType>();
5181-
return {isVariadic, autoclosure, escaping, inOut, isShared};
5189+
if (paramTy->is<InOutType>()) {
5190+
assert(ownership == ValueOwnership::Default ||
5191+
ownership == ValueOwnership::InOut);
5192+
ownership = ValueOwnership::InOut;
5193+
}
5194+
return {isVariadic, autoclosure, escaping, ownership};
51825195
}
51835196

51845197
inline const Type *BoundGenericType::getTrailingObjectsPointer() const {

include/swift/Serialization/ModuleFormat.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 400; // Last change: sil_property
58+
const uint16_t VERSION_MINOR = 401; // Last change: ValueOwnership
5959

6060
using DeclIDField = BCFixed<31>;
6161

@@ -319,6 +319,15 @@ enum ReferenceOwnership : uint8_t {
319319
};
320320
using ReferenceOwnershipField = BCFixed<2>;
321321

322+
// These IDs must \em not be renumbered or reordered without incrementing
323+
// VERSION_MAJOR.
324+
enum ValueOwnership : uint8_t {
325+
Default = 0,
326+
InOut,
327+
Shared,
328+
};
329+
using ValueOwnershipField = BCFixed<2>;
330+
322331
// These IDs must \em not be renumbered or reordered without incrementing
323332
// VERSION_MAJOR.
324333
enum class DefaultArgumentKind : uint8_t {
@@ -656,8 +665,7 @@ namespace decls_block {
656665
BCFixed<1>, // vararg?
657666
BCFixed<1>, // autoclosure?
658667
BCFixed<1>, // escaping?
659-
BCFixed<1>, // inout?
660-
BCFixed<1> // shared?
668+
ValueOwnershipField // inout, shared or owned?
661669
>;
662670

663671
using TupleTypeLayout = BCRecordLayout<
@@ -671,8 +679,7 @@ namespace decls_block {
671679
BCFixed<1>, // vararg?
672680
BCFixed<1>, // autoclosure?
673681
BCFixed<1>, // escaping?
674-
BCFixed<1>, // inout?
675-
BCFixed<1> // shared?
682+
ValueOwnershipField // inout, shared or owned?
676683
>;
677684

678685
using FunctionTypeLayout = BCRecordLayout<

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,9 +3566,10 @@ void AnyFunctionType::decomposeInput(
35663566

35673567
default:
35683568
// assert(type->is<InOutType>() && "Found naked inout type");
3569-
result.push_back(AnyFunctionType::Param(type->getInOutObjectType(),
3570-
Identifier(),
3571-
ParameterTypeFlags::fromParameterType(type, false, false)));
3569+
result.push_back(
3570+
AnyFunctionType::Param(type->getInOutObjectType(), Identifier(),
3571+
ParameterTypeFlags::fromParameterType(
3572+
type, false, ValueOwnership::Default)));
35723573
return;
35733574
}
35743575
}

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4416,8 +4416,8 @@ ParamDecl *ParamDecl::createSelf(SourceLoc loc, DeclContext *DC,
44164416
}
44174417

44184418
ParameterTypeFlags ParamDecl::getParameterFlags() const {
4419-
return ParameterTypeFlags::fromParameterType(getType(), isVariadic(), isShared())
4420-
.withInOut(isInOut());
4419+
return ParameterTypeFlags::fromParameterType(getType(), isVariadic(),
4420+
getValueOwnership());
44214421
}
44224422

44234423
/// Return the full source range of this parameter.

lib/AST/Parameter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ Type ParameterList::getType(
127127

128128
for (auto P : *this) {
129129
auto type = getType(P);
130-
argumentInfo.emplace_back(type->getInOutObjectType(), P->getArgumentName(),
131-
ParameterTypeFlags::fromParameterType(
132-
type, P->isVariadic(), P->isShared())
133-
.withInOut(P->isInOut()));
130+
argumentInfo.emplace_back(
131+
type->getInOutObjectType(), P->getArgumentName(),
132+
ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
133+
P->getValueOwnership()));
134134
}
135135

136136
return TupleType::get(argumentInfo, C);

lib/Sema/TypeCheckType.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,10 +2854,20 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
28542854

28552855
ParameterTypeFlags paramFlags;
28562856
if (isImmediateFunctionInput) {
2857-
bool isShared = (tyR->getKind() == TypeReprKind::Shared);
2858-
bool isInOut = (tyR->getKind() == TypeReprKind::InOut);
2859-
paramFlags = ParameterTypeFlags::fromParameterType(ty, variadic, isShared)
2860-
.withInOut(isInOut);
2857+
ValueOwnership ownership;
2858+
switch (tyR->getKind()) {
2859+
case TypeReprKind::Shared:
2860+
ownership = ValueOwnership::Shared;
2861+
break;
2862+
case TypeReprKind::InOut:
2863+
ownership = ValueOwnership::InOut;
2864+
break;
2865+
default:
2866+
ownership = ValueOwnership::Default;
2867+
break;
2868+
}
2869+
paramFlags =
2870+
ParameterTypeFlags::fromParameterType(ty, variadic, ownership);
28612871
}
28622872
elements.emplace_back(ty->getInOutObjectType(), name, paramFlags);
28632873
}

lib/Serialization/Deserialization.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,22 @@ getActualReferenceOwnership(serialization::ReferenceOwnership raw) {
40134013
return None;
40144014
}
40154015

4016+
/// Translate from the serialization ValueOwnership enumerators, which are
4017+
/// guaranteed to be stable, to the AST ones.
4018+
static Optional<swift::ValueOwnership>
4019+
getActualValueOwnership(serialization::ValueOwnership raw) {
4020+
switch (raw) {
4021+
#define CASE(ID) \
4022+
case serialization::ValueOwnership::ID: \
4023+
return swift::ValueOwnership::ID;
4024+
CASE(Default)
4025+
CASE(InOut)
4026+
CASE(Shared)
4027+
#undef CASE
4028+
}
4029+
return None;
4030+
}
4031+
40164032
/// Translate from the serialization ParameterConvention enumerators,
40174033
/// which are guaranteed to be stable, to the AST ones.
40184034
static
@@ -4153,19 +4169,25 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
41534169

41544170
case decls_block::PAREN_TYPE: {
41554171
TypeID underlyingID;
4156-
bool isVariadic, isAutoClosure, isEscaping, isInOut, isShared;
4172+
bool isVariadic, isAutoClosure, isEscaping;
4173+
unsigned rawOwnership;
41574174
decls_block::ParenTypeLayout::readRecord(scratch, underlyingID, isVariadic,
41584175
isAutoClosure, isEscaping,
4159-
isInOut, isShared);
4176+
rawOwnership);
4177+
auto ownership =
4178+
getActualValueOwnership((serialization::ValueOwnership)rawOwnership);
4179+
if (!ownership) {
4180+
error();
4181+
return nullptr;
4182+
}
41604183

41614184
auto underlyingTy = getTypeChecked(underlyingID);
41624185
if (!underlyingTy)
41634186
return underlyingTy.takeError();
4164-
4187+
41654188
typeOrOffset = ParenType::get(
41664189
ctx, underlyingTy.get()->getInOutObjectType(),
4167-
ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping,
4168-
isInOut, isShared));
4190+
ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping, *ownership));
41694191
break;
41704192
}
41714193

@@ -4185,19 +4207,27 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
41854207

41864208
IdentifierID nameID;
41874209
TypeID typeID;
4188-
bool isVariadic, isAutoClosure, isEscaping, isInOut, isShared;
4189-
decls_block::TupleTypeEltLayout::readRecord(
4190-
scratch, nameID, typeID, isVariadic, isAutoClosure, isEscaping,
4191-
isInOut, isShared);
4210+
bool isVariadic, isAutoClosure, isEscaping;
4211+
unsigned rawOwnership;
4212+
decls_block::TupleTypeEltLayout::readRecord(scratch, nameID, typeID,
4213+
isVariadic, isAutoClosure,
4214+
isEscaping, rawOwnership);
4215+
4216+
auto ownership =
4217+
getActualValueOwnership((serialization::ValueOwnership)rawOwnership);
4218+
if (!ownership) {
4219+
error();
4220+
return nullptr;
4221+
}
41924222

41934223
auto elementTy = getTypeChecked(typeID);
41944224
if (!elementTy)
41954225
return elementTy.takeError();
4196-
4197-
elements.emplace_back(
4198-
elementTy.get()->getInOutObjectType(), getIdentifier(nameID),
4199-
ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping,
4200-
isInOut, isShared));
4226+
4227+
elements.emplace_back(elementTy.get()->getInOutObjectType(),
4228+
getIdentifier(nameID),
4229+
ParameterTypeFlags(isVariadic, isAutoClosure,
4230+
isEscaping, *ownership));
42014231
}
42024232

42034233
typeOrOffset = TupleType::get(elements, ctx);

lib/Serialization/Serialization.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,6 +3488,16 @@ getRawStableReferenceOwnership(swift::ReferenceOwnership ownership) {
34883488
}
34893489
llvm_unreachable("bad ownership kind");
34903490
}
3491+
/// Translate from the AST ownership enum to the Serialization enum
3492+
/// values, which are guaranteed to be stable.
3493+
static uint8_t getRawStableValueOwnership(swift::ValueOwnership ownership) {
3494+
switch (ownership) {
3495+
SIMPLE_CASE(ValueOwnership, Default)
3496+
SIMPLE_CASE(ValueOwnership, InOut)
3497+
SIMPLE_CASE(ValueOwnership, Shared)
3498+
}
3499+
llvm_unreachable("bad ownership kind");
3500+
}
34913501

34923502
/// Translate from the AST ParameterConvention enum to the
34933503
/// Serialization enum values, which are guaranteed to be stable.
@@ -3590,12 +3600,14 @@ void Serializer::writeType(Type ty) {
35903600
case TypeKind::Paren: {
35913601
auto parenTy = cast<ParenType>(ty.getPointer());
35923602
auto paramFlags = parenTy->getParameterFlags();
3603+
auto rawOwnership =
3604+
getRawStableValueOwnership(paramFlags.getValueOwnership());
35933605

35943606
unsigned abbrCode = DeclTypeAbbrCodes[ParenTypeLayout::Code];
35953607
ParenTypeLayout::emitRecord(
35963608
Out, ScratchRecord, abbrCode, addTypeRef(parenTy->getUnderlyingType()),
35973609
paramFlags.isVariadic(), paramFlags.isAutoClosure(),
3598-
paramFlags.isEscaping(), paramFlags.isInOut(), paramFlags.isShared());
3610+
paramFlags.isEscaping(), rawOwnership);
35993611
break;
36003612
}
36013613

@@ -3608,11 +3620,12 @@ void Serializer::writeType(Type ty) {
36083620
abbrCode = DeclTypeAbbrCodes[TupleTypeEltLayout::Code];
36093621
for (auto &elt : tupleTy->getElements()) {
36103622
auto paramFlags = elt.getParameterFlags();
3623+
auto rawOwnership =
3624+
getRawStableValueOwnership(paramFlags.getValueOwnership());
36113625
TupleTypeEltLayout::emitRecord(
36123626
Out, ScratchRecord, abbrCode, addDeclBaseNameRef(elt.getName()),
36133627
addTypeRef(elt.getType()), paramFlags.isVariadic(),
3614-
paramFlags.isAutoClosure(), paramFlags.isEscaping(),
3615-
paramFlags.isInOut(), paramFlags.isShared());
3628+
paramFlags.isAutoClosure(), paramFlags.isEscaping(), rawOwnership);
36163629
}
36173630

36183631
break;

0 commit comments

Comments
 (0)