Skip to content

Commit 8702fe7

Browse files
committed
Requestify AbstractStorageDecl::hasStorage().
The `hasStorage()` computation is used in many places to determine the signatures of other declarations. It currently needs to expand accessor macros, which causes a number of cyclic references. Provide a simplified request to determine `hasStorage` without expanding or resolving macros, breaking a common pattern of cycles when using macros. Fixes rdar://109668383.
1 parent 66a38a1 commit 8702fe7

File tree

18 files changed

+222
-22
lines changed

18 files changed

+222
-22
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5295,10 +5295,7 @@ class AbstractStorageDecl : public ValueDecl {
52955295

52965296
/// Overwrite the registered implementation-info. This should be
52975297
/// used carefully.
5298-
void setImplInfo(StorageImplInfo implInfo) {
5299-
LazySemanticInfo.ImplInfoComputed = 1;
5300-
ImplInfo = implInfo;
5301-
}
5298+
void setImplInfo(StorageImplInfo implInfo);
53025299

53035300
ReadImplKind getReadImpl() const {
53045301
return getImplInfo().getReadImpl();
@@ -5313,9 +5310,7 @@ class AbstractStorageDecl : public ValueDecl {
53135310

53145311
/// Return true if this is a VarDecl that has storage associated with
53155312
/// it.
5316-
bool hasStorage() const {
5317-
return getImplInfo().hasStorage();
5318-
}
5313+
bool hasStorage() const;
53195314

53205315
/// Return true if this storage has the basic accessors/capability
53215316
/// to be mutated. This is generally constant after the accessors are

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7085,6 +7085,10 @@ ERROR(invalid_macro_role_for_macro_syntax,none,
70857085
(unsigned))
70867086
ERROR(macro_cannot_introduce_names,none,
70877087
"'%0' macros are not allowed to introduce names", (StringRef))
7088+
ERROR(macro_accessor_missing_from_expansion,none,
7089+
"expansion of macro %0 did not produce a %select{non-|}1observing "
7090+
"accessor",
7091+
(DeclName, bool))
70887092

70897093
ERROR(macro_resolve_circular_reference, none,
70907094
"circular reference resolving %select{freestanding|attached}0 macro %1",

include/swift/AST/Evaluator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ class Evaluator {
316316
cache.insert<Request>(request, std::move(output));
317317
}
318318

319+
template<typename Request,
320+
typename std::enable_if<!Request::hasExternalCache>::type* = nullptr>
321+
bool hasCachedResult(const Request &request) {
322+
return cache.find_as(request) != cache.end<Request>();
323+
}
324+
319325
/// Do not introduce new callers of this function.
320326
template<typename Request,
321327
typename std::enable_if<!Request::hasExternalCache>::type* = nullptr>

include/swift/AST/NameLookup.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,13 @@ void forEachPotentialResolvedMacro(
555555
llvm::function_ref<void(MacroDecl *, const MacroRoleAttr *)> body
556556
);
557557

558+
/// For each macro with the given role that might be attached to the given
559+
/// declaration, call the body.
560+
void forEachPotentialAttachedMacro(
561+
Decl *decl, MacroRole role,
562+
llvm::function_ref<void(MacroDecl *macro, const MacroRoleAttr *)> body
563+
);
564+
558565
} // end namespace namelookup
559566

560567
/// Describes an inherited nominal entry.

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,26 @@ class InitAccessorPropertiesRequest :
16861686
ArrayRef<VarDecl *>
16871687
evaluate(Evaluator &evaluator, NominalTypeDecl *decl) const;
16881688

1689+
// Evaluation.
1690+
bool evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
1691+
1692+
public:
1693+
bool isCached() const { return true; }
1694+
};
1695+
1696+
class HasStorageRequest :
1697+
public SimpleRequest<HasStorageRequest,
1698+
bool(AbstractStorageDecl *),
1699+
RequestFlags::Cached> {
1700+
public:
1701+
using SimpleRequest::SimpleRequest;
1702+
1703+
private:
1704+
friend SimpleRequest;
1705+
1706+
// Evaluation.
1707+
bool evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
1708+
16891709
public:
16901710
bool isCached() const { return true; }
16911711
};

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ SWIFT_REQUEST(TypeChecker, SelfAccessKindRequest, SelfAccessKind(FuncDecl *),
302302
SWIFT_REQUEST(TypeChecker, StorageImplInfoRequest,
303303
StorageImplInfo(AbstractStorageDecl *), SeparatelyCached,
304304
NoLocationInfo)
305+
SWIFT_REQUEST(TypeChecker, HasStorageRequest,
306+
bool(AbstractStorageDecl *), Cached,
307+
NoLocationInfo)
305308
SWIFT_REQUEST(TypeChecker, StoredPropertiesAndMissingMembersRequest,
306309
ArrayRef<Decl *>(NominalTypeDecl *), Cached, NoLocationInfo)
307310
SWIFT_REQUEST(TypeChecker, StoredPropertiesRequest,

lib/AST/Decl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6378,13 +6378,32 @@ bool ProtocolDecl::hasCircularInheritedProtocols() const {
63786378
ctx.evaluator, HasCircularInheritedProtocolsRequest{mutableThis}, true);
63796379
}
63806380

6381+
bool AbstractStorageDecl::hasStorage() const {
6382+
ASTContext &ctx = getASTContext();
6383+
return evaluateOrDefault(ctx.evaluator,
6384+
HasStorageRequest{const_cast<AbstractStorageDecl *>(this)},
6385+
false);
6386+
}
6387+
63816388
StorageImplInfo AbstractStorageDecl::getImplInfo() const {
63826389
ASTContext &ctx = getASTContext();
63836390
return evaluateOrDefault(ctx.evaluator,
63846391
StorageImplInfoRequest{const_cast<AbstractStorageDecl *>(this)},
63856392
StorageImplInfo::getSimpleStored(StorageIsMutable));
63866393
}
63876394

6395+
void AbstractStorageDecl::setImplInfo(StorageImplInfo implInfo) {
6396+
LazySemanticInfo.ImplInfoComputed = 1;
6397+
ImplInfo = implInfo;
6398+
6399+
if (isImplicit()) {
6400+
auto &evaluator = getASTContext().evaluator;
6401+
HasStorageRequest request{this};
6402+
if (!evaluator.hasCachedResult(request))
6403+
evaluator.cacheOutput(request, implInfo.hasStorage());
6404+
}
6405+
}
6406+
63886407
bool AbstractStorageDecl::hasPrivateAccessor() const {
63896408
for (auto accessor : getAllAccessors()) {
63906409
if (hasPrivateOrFilePrivateFormalAccess(accessor))

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1627,7 +1627,7 @@ void namelookup::forEachPotentialResolvedMacro(
16271627

16281628
/// For each macro with the given role that might be attached to the given
16291629
/// declaration, call the body.
1630-
static void forEachPotentialAttachedMacro(
1630+
void namelookup::forEachPotentialAttachedMacro(
16311631
Decl *decl, MacroRole role,
16321632
llvm::function_ref<void(MacroDecl *macro, const MacroRoleAttr *)> body
16331633
) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "swift/AST/NameLookupRequests.h"
3535
#include "swift/AST/PrettyStackTrace.h"
3636
#include "swift/AST/SourceFile.h"
37+
#include "swift/AST/TypeCheckRequests.h"
3738
#include "swift/AST/Types.h"
3839
#include "swift/Basic/Defer.h"
3940
#include "swift/Basic/Platform.h"
@@ -5042,6 +5043,7 @@ cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
50425043
out->setIsObjC(var->isObjC());
50435044
out->setIsDynamic(var->isDynamic());
50445045
out->copyFormalAccessFrom(var);
5046+
out->getASTContext().evaluator.cacheOutput(HasStorageRequest{out}, false);
50455047
out->setAccessors(SourceLoc(),
50465048
makeBaseClassMemberAccessors(newContext, out, var),
50475049
SourceLoc());

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ void ClangImporter::Implementation::makeComputed(AbstractStorageDecl *storage,
126126
AccessorDecl *getter,
127127
AccessorDecl *setter) {
128128
assert(getter);
129+
storage->getASTContext().evaluator.cacheOutput(HasStorageRequest{storage}, false);
129130
if (setter) {
130131
storage->setImplInfo(StorageImplInfo::getMutableComputed());
131132
storage->setAccessors(SourceLoc(), {getter, setter}, SourceLoc());

0 commit comments

Comments
 (0)