Skip to content

Commit 4851942

Browse files
authored
Merge pull request #26381 from slavapestov/synthesize-accessor-request
Request-ify accessor synthesis
2 parents 72ce94a + 28d1466 commit 4851942

22 files changed

+475
-354
lines changed

include/swift/AST/Decl.h

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,15 @@ class alignas(1 << DeclAlignInBits) Decl {
445445
SelfAccess : 2
446446
);
447447

448-
SWIFT_INLINE_BITFIELD(AccessorDecl, FuncDecl, 4,
448+
SWIFT_INLINE_BITFIELD(AccessorDecl, FuncDecl, 4+1+1,
449449
/// The kind of accessor this is.
450-
AccessorKind : 4
450+
AccessorKind : 4,
451+
452+
/// Whether the accessor is transparent.
453+
IsTransparent : 1,
454+
455+
/// Whether we have computed the above.
456+
IsTransparentComputed : 1
451457
);
452458

453459
SWIFT_INLINE_BITFIELD(ConstructorDecl, AbstractFunctionDecl, 3+2+1,
@@ -4389,6 +4395,9 @@ class AbstractStorageDecl : public ValueDecl {
43894395
friend class IsSetterMutatingRequest;
43904396
friend class OpaqueReadOwnershipRequest;
43914397
friend class StorageImplInfoRequest;
4398+
friend class RequiresOpaqueAccessorsRequest;
4399+
friend class RequiresOpaqueModifyCoroutineRequest;
4400+
friend class SynthesizeAccessorRequest;
43924401

43934402
public:
43944403
static const size_t MaxNumAccessors = 255;
@@ -4452,11 +4461,18 @@ class AbstractStorageDecl : public ValueDecl {
44524461
unsigned OpaqueReadOwnershipComputed : 1;
44534462
unsigned OpaqueReadOwnership : 2;
44544463
unsigned ImplInfoComputed : 1;
4464+
unsigned RequiresOpaqueAccessorsComputed : 1;
4465+
unsigned RequiresOpaqueAccessors : 1;
4466+
unsigned RequiresOpaqueModifyCoroutineComputed : 1;
4467+
unsigned RequiresOpaqueModifyCoroutine : 1;
44554468
} LazySemanticInfo = { };
44564469

44574470
/// The implementation info for the accessors.
44584471
StorageImplInfo ImplInfo;
44594472

4473+
/// Add a synthesized accessor.
4474+
void setSynthesizedAccessor(AccessorKind kind, AccessorDecl *getter);
4475+
44604476
protected:
44614477
AbstractStorageDecl(DeclKind Kind, bool IsStatic, DeclContext *DC,
44624478
DeclName Name, SourceLoc NameLoc,
@@ -4570,6 +4586,12 @@ class AbstractStorageDecl : public ValueDecl {
45704586
return {};
45714587
}
45724588

4589+
/// Return an accessor that this storage is expected to have, synthesizing
4590+
/// one if necessary. Note that will always synthesize one, even if the
4591+
/// accessor is not part of the expected opaque set for the storage, so use
4592+
/// with caution.
4593+
AccessorDecl *getSynthesizedAccessor(AccessorKind kind) const;
4594+
45734595
/// Visit all the opaque accessors that this storage is expected to have.
45744596
void visitExpectedOpaqueAccessors(
45754597
llvm::function_ref<void (AccessorKind)>) const;
@@ -4585,17 +4607,8 @@ class AbstractStorageDecl : public ValueDecl {
45854607
/// This should only be used by the ClangImporter.
45864608
void setComputedSetter(AccessorDecl *Set);
45874609

4588-
/// Add a synthesized getter.
4589-
void setSynthesizedGetter(AccessorDecl *getter);
4590-
4591-
/// Add a synthesized setter.
4592-
void setSynthesizedSetter(AccessorDecl *setter);
4593-
4594-
/// Add a synthesized read coroutine.
4595-
void setSynthesizedReadCoroutine(AccessorDecl *read);
4596-
4597-
/// Add a synthesized modify coroutine.
4598-
void setSynthesizedModifyCoroutine(AccessorDecl *modify);
4610+
/// Does this storage require opaque accessors of any kind?
4611+
bool requiresOpaqueAccessors() const;
45994612

46004613
/// Does this storage require an opaque accessor of the given kind?
46014614
bool requiresOpaqueAccessor(AccessorKind kind) const;
@@ -6151,6 +6164,14 @@ class AccessorDecl final : public FuncDecl {
61516164
DeclContext *parent,
61526165
ClangNode clangNode);
61536166

6167+
Optional<bool> getCachedIsTransparent() const {
6168+
if (Bits.AccessorDecl.IsTransparentComputed)
6169+
return Bits.AccessorDecl.IsTransparent;
6170+
return None;
6171+
}
6172+
6173+
friend class IsAccessorTransparentRequest;
6174+
61546175
public:
61556176
static AccessorDecl *createDeserialized(ASTContext &ctx,
61566177
SourceLoc declLoc,
@@ -6229,6 +6250,11 @@ class AccessorDecl final : public FuncDecl {
62296250
llvm_unreachable("bad accessor kind");
62306251
}
62316252

6253+
void setIsTransparent(bool transparent) {
6254+
Bits.AccessorDecl.IsTransparent = transparent;
6255+
Bits.AccessorDecl.IsTransparentComputed = 1;
6256+
}
6257+
62326258
static bool classof(const Decl *D) {
62336259
return D->getKind() == DeclKind::Accessor;
62346260
}

include/swift/AST/StorageImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ class StorageImplInfo {
383383
}
384384
};
385385

386+
StringRef getAccessorLabel(AccessorKind kind);
387+
void simple_display(llvm::raw_ostream &out, AccessorKind kind);
388+
386389
} // end namespace swift
387390

388391
#endif

include/swift/AST/TypeCheckRequests.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,92 @@ class StorageImplInfoRequest :
901901
void cacheResult(StorageImplInfo value) const;
902902
};
903903

904+
class RequiresOpaqueAccessorsRequest :
905+
public SimpleRequest<RequiresOpaqueAccessorsRequest,
906+
bool(VarDecl *),
907+
CacheKind::SeparatelyCached> {
908+
public:
909+
using SimpleRequest::SimpleRequest;
910+
911+
private:
912+
friend SimpleRequest;
913+
914+
// Evaluation.
915+
llvm::Expected<bool>
916+
evaluate(Evaluator &evaluator, VarDecl *decl) const;
917+
918+
public:
919+
// Separate caching.
920+
bool isCached() const { return true; }
921+
Optional<bool> getCachedResult() const;
922+
void cacheResult(bool value) const;
923+
};
924+
925+
class RequiresOpaqueModifyCoroutineRequest :
926+
public SimpleRequest<RequiresOpaqueModifyCoroutineRequest,
927+
bool(AbstractStorageDecl *),
928+
CacheKind::SeparatelyCached> {
929+
public:
930+
using SimpleRequest::SimpleRequest;
931+
932+
private:
933+
friend SimpleRequest;
934+
935+
// Evaluation.
936+
llvm::Expected<bool>
937+
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
938+
939+
public:
940+
// Separate caching.
941+
bool isCached() const { return true; }
942+
Optional<bool> getCachedResult() const;
943+
void cacheResult(bool value) const;
944+
};
945+
946+
class IsAccessorTransparentRequest :
947+
public SimpleRequest<IsAccessorTransparentRequest,
948+
bool(AccessorDecl *),
949+
CacheKind::SeparatelyCached> {
950+
public:
951+
using SimpleRequest::SimpleRequest;
952+
953+
private:
954+
friend SimpleRequest;
955+
956+
// Evaluation.
957+
llvm::Expected<bool>
958+
evaluate(Evaluator &evaluator, AccessorDecl *decl) const;
959+
960+
public:
961+
// Separate caching.
962+
bool isCached() const { return true; }
963+
Optional<bool> getCachedResult() const;
964+
void cacheResult(bool value) const;
965+
};
966+
967+
class SynthesizeAccessorRequest :
968+
public SimpleRequest<SynthesizeAccessorRequest,
969+
AccessorDecl *(AbstractStorageDecl *,
970+
AccessorKind),
971+
CacheKind::SeparatelyCached> {
972+
public:
973+
using SimpleRequest::SimpleRequest;
974+
975+
private:
976+
friend SimpleRequest;
977+
978+
// Evaluation.
979+
llvm::Expected<AccessorDecl *>
980+
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl,
981+
AccessorKind kind) const;
982+
983+
public:
984+
// Separate caching.
985+
bool isCached() const { return true; }
986+
Optional<AccessorDecl *> getCachedResult() const;
987+
void cacheResult(AccessorDecl *value) const;
988+
};
989+
904990
// Allow AnyValue to compare two Type values, even though Type doesn't
905991
// support ==.
906992
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,7 @@ SWIFT_TYPEID(TypeCheckFunctionBodyUntilRequest)
4949
SWIFT_TYPEID(StoredPropertiesRequest)
5050
SWIFT_TYPEID(StoredPropertiesAndMissingMembersRequest)
5151
SWIFT_TYPEID(StorageImplInfoRequest)
52+
SWIFT_TYPEID(RequiresOpaqueAccessorsRequest)
53+
SWIFT_TYPEID(RequiresOpaqueModifyCoroutineRequest)
54+
SWIFT_TYPEID(IsAccessorTransparentRequest)
55+
SWIFT_TYPEID(SynthesizeAccessorRequest)

include/swift/SIL/SILVTableVisitor.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,6 @@ template <class T> class SILVTableVisitor {
100100
}
101101

102102
void maybeAddAccessors(AbstractStorageDecl *asd) {
103-
// FIXME: This should not be necessary once visitOpaqueAccessors()
104-
// incorporates the logic currently in maybeAddAccessorsToStorage().
105-
if (!asd->hasAnyAccessors())
106-
return;
107-
108103
asd->visitOpaqueAccessors([&](AccessorDecl *accessor) {
109104
maybeAddMethod(accessor);
110105
});

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 505; // track vtable entries for storage
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 506; // transparent accessor bit
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1139,6 +1139,7 @@ namespace decls_block {
11391139
AccessorKindField, // accessor kind
11401140
AccessLevelField, // access level
11411141
BCFixed<1>, // requires a new vtable slot
1142+
BCFixed<1>, // is transparent
11421143
BCArray<IdentifierIDField> // name components,
11431144
// followed by TypeID dependencies
11441145
// The record is trailed by:

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,16 +1704,6 @@ void PrintAST::printBodyIfNecessary(const AbstractFunctionDecl *decl) {
17041704
printBraceStmt(decl->getBody(), /*newlineIfEmpty*/!isa<AccessorDecl>(decl));
17051705
}
17061706

1707-
static StringRef getAccessorLabel(AccessorDecl *accessor) {
1708-
switch (accessor->getAccessorKind()) {
1709-
#define SINGLETON_ACCESSOR(ID, KEYWORD) \
1710-
case AccessorKind::ID: return #KEYWORD;
1711-
#define ACCESSOR(ID)
1712-
#include "swift/AST/AccessorKinds.def"
1713-
}
1714-
llvm_unreachable("bad accessor kind");
1715-
}
1716-
17171707
void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) {
17181708
if (accessor->isAssumedNonMutating() && accessor->isMutating()) {
17191709
Printer.printKeyword("mutating", Options, " ");
@@ -1830,7 +1820,7 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
18301820
if (!PrintAccessorBody) {
18311821
Printer << " ";
18321822
printMutatingModifiersIfNeeded(Accessor);
1833-
Printer.printKeyword(getAccessorLabel(Accessor), Options);
1823+
Printer.printKeyword(getAccessorLabel(Accessor->getAccessorKind()), Options);
18341824
} else {
18351825
{
18361826
IndentRAII IndentMore(*this);
@@ -2719,14 +2709,14 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
27192709
case AccessorKind::MutableAddress:
27202710
recordDeclLoc(decl,
27212711
[&]{
2722-
Printer << getAccessorLabel(decl);
2712+
Printer << getAccessorLabel(decl->getAccessorKind());
27232713
});
27242714
break;
27252715
case AccessorKind::Set:
27262716
case AccessorKind::WillSet:
27272717
recordDeclLoc(decl,
27282718
[&]{
2729-
Printer << getAccessorLabel(decl);
2719+
Printer << getAccessorLabel(decl->getAccessorKind());
27302720

27312721
auto params = decl->getParameters();
27322722
if (params->size() != 0 && !params->get(0)->isImplicit()) {

0 commit comments

Comments
 (0)