Skip to content

Commit 2f512f5

Browse files
committed
Merge branch 'semantic-availability-spec-request' into tmp
2 parents c4ee20d + 3ea979f commit 2f512f5

File tree

5 files changed

+96
-13
lines changed

5 files changed

+96
-13
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ class AvailabilityDomainOrIdentifier {
330330
std::optional<AvailabilityDomain>
331331
lookUpInDeclContext(SourceLoc loc, const DeclContext *declContext) const;
332332

333+
void setResolved(std::optional<AvailabilityDomain> domain) {
334+
if (domain)
335+
storage.setPointer(*domain);
336+
storage.setInt(true);
337+
}
338+
333339
public:
334340
AvailabilityDomainOrIdentifier(Identifier identifier)
335341
: storage(identifier) {};
@@ -359,18 +365,19 @@ class AvailabilityDomainOrIdentifier {
359365
return std::nullopt;
360366
}
361367

368+
/// Returns true if either a resolved domain is available or if the attempt
369+
/// to look up the domain from the identifier was unsuccessful.
370+
bool isResolved() const { return storage.getInt() || isDomain(); }
371+
362372
std::optional<AvailabilityDomain>
363373
resolveInDeclContext(SourceLoc loc, const DeclContext *declContext) {
364374
// Return the domain directly if already resolved.
365-
if (storage.getInt() || isDomain())
375+
if (isResolved())
366376
return getAsDomain();
367377

368378
// Look up the domain and cache the result.
369379
auto result = lookUpInDeclContext(loc, declContext);
370-
if (result)
371-
storage.setPointer(*result);
372-
storage.setInt(true);
373-
380+
setResolved(result);
374381
return result;
375382
}
376383

include/swift/AST/AvailabilitySpec.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
5050
// Location of the availability macro expanded to create this spec.
5151
SourceLoc MacroLoc;
5252

53+
unsigned IsInvalid : 1;
54+
5355
AvailabilitySpec(AvailabilityDomainOrIdentifier DomainOrIdentifier,
5456
SourceRange SrcRange, llvm::VersionTuple Version,
5557
SourceLoc VersionStartLoc)
5658
: DomainOrIdentifier(DomainOrIdentifier), SrcRange(SrcRange),
57-
Version(Version), VersionStartLoc(VersionStartLoc) {}
59+
Version(Version), VersionStartLoc(VersionStartLoc), IsInvalid(false) {}
5860

5961
public:
6062
/// Creates a wildcard availability specification that guards execution
@@ -91,6 +93,9 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
9193
SourceRange getSourceRange() const { return SrcRange; }
9294
SourceLoc getStartLoc() const { return SrcRange.Start; }
9395

96+
/// Returns true if this spec did not type-check successfully.
97+
bool isInvalid() const { return IsInvalid; }
98+
9499
AvailabilityDomainOrIdentifier getDomainOrIdentifier() const {
95100
return DomainOrIdentifier;
96101
}
@@ -115,6 +120,14 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
115120
void setMacroLoc(SourceLoc loc) { MacroLoc = loc; }
116121

117122
void print(llvm::raw_ostream &os) const;
123+
124+
private:
125+
friend class SemanticAvailabilitySpecRequest;
126+
127+
std::optional<AvailabilityDomain>
128+
resolveInDeclContext(const DeclContext *declContext);
129+
130+
void setInvalid() { IsInvalid = true; }
118131
};
119132

120133
inline void simple_display(llvm::raw_ostream &os,

include/swift/AST/TypeCheckRequests.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/ASTTypeIDs.h"
2121
#include "swift/AST/ActorIsolation.h"
2222
#include "swift/AST/AnyFunctionRef.h"
23+
#include "swift/AST/AvailabilitySpec.h"
2324
#include "swift/AST/CatchNode.h"
2425
#include "swift/AST/Effects.h"
2526
#include "swift/AST/Evaluator.h"
@@ -5228,6 +5229,28 @@ class SemanticAvailableAttrRequest
52285229
void cacheResult(std::optional<SemanticAvailableAttr> value) const;
52295230
};
52305231

5232+
class SemanticAvailabilitySpecRequest
5233+
: public SimpleRequest<SemanticAvailabilitySpecRequest,
5234+
std::optional<SemanticAvailabilitySpec>(
5235+
const AvailabilitySpec *, const DeclContext *),
5236+
RequestFlags::SeparatelyCached> {
5237+
public:
5238+
using SimpleRequest::SimpleRequest;
5239+
5240+
private:
5241+
friend SimpleRequest;
5242+
5243+
std::optional<SemanticAvailabilitySpec>
5244+
evaluate(Evaluator &evaluator, const AvailabilitySpec *spec,
5245+
const DeclContext *declContext) const;
5246+
5247+
public:
5248+
bool isCached() const { return true; }
5249+
std::optional<std::optional<SemanticAvailabilitySpec>>
5250+
getCachedResult() const;
5251+
void cacheResult(std::optional<SemanticAvailabilitySpec> value) const;
5252+
};
5253+
52315254
#define SWIFT_TYPEID_ZONE TypeChecker
52325255
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
52335256
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,7 @@ SWIFT_REQUEST(TypeChecker, SemanticAvailableAttrRequest,
616616
std::optional<SemanticAvailableAttr>
617617
(const AvailableAttr *, const Decl *),
618618
SeparatelyCached, NoLocationInfo)
619+
SWIFT_REQUEST(TypeChecker, SemanticAvailabilitySpecRequest,
620+
std::optional<SemanticAvailabilitySpec>
621+
(const AvailabilitySpec *, const DeclContext *),
622+
SeparatelyCached, NoLocationInfo)

lib/AST/AvailabilitySpec.cpp

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/AvailabilityDomain.h"
2020
#include "swift/AST/DiagnosticsParse.h"
21+
#include "swift/AST/TypeCheckRequests.h"
2122
#include "llvm/Support/raw_ostream.h"
2223

2324
using namespace swift;
@@ -70,16 +71,21 @@ void AvailabilitySpec::print(llvm::raw_ostream &os) const {
7071
os << " " << getRawVersion().getAsString();
7172
}
7273

74+
std::optional<AvailabilityDomain>
75+
AvailabilitySpec::resolveInDeclContext(const DeclContext *declContext) {
76+
auto domainOrIdentifier = getDomainOrIdentifier();
77+
auto result =
78+
domainOrIdentifier.resolveInDeclContext(getStartLoc(), declContext);
79+
DomainOrIdentifier = domainOrIdentifier;
80+
return result;
81+
}
82+
7383
std::optional<SemanticAvailabilitySpec>
7484
AvailabilitySpec::getSemanticAvailabilitySpec(
7585
const DeclContext *declContext) const {
76-
AvailabilitySpec *mutableThis = const_cast<AvailabilitySpec *>(this);
77-
auto domain = mutableThis->DomainOrIdentifier.resolveInDeclContext(
78-
getStartLoc(), declContext);
79-
80-
if (domain)
81-
return SemanticAvailabilitySpec(this);
82-
return std::nullopt;
86+
return evaluateOrDefault(declContext->getASTContext().evaluator,
87+
SemanticAvailabilitySpecRequest{this, declContext},
88+
std::nullopt);
8389
}
8490

8591
llvm::VersionTuple SemanticAvailabilitySpec::getVersion() const {
@@ -105,3 +111,33 @@ SemanticAvailabilitySpecs::Filter::operator()(
105111
return semanticSpec;
106112
return std::nullopt;
107113
}
114+
115+
std::optional<SemanticAvailabilitySpec>
116+
SemanticAvailabilitySpecRequest::evaluate(
117+
Evaluator &evaluator, const AvailabilitySpec *spec,
118+
const DeclContext *declContext) const {
119+
AvailabilitySpec *mutableSpec = const_cast<AvailabilitySpec *>(spec);
120+
if (mutableSpec->resolveInDeclContext(declContext).has_value())
121+
return SemanticAvailabilitySpec(spec);
122+
return std::nullopt;
123+
}
124+
125+
std::optional<std::optional<SemanticAvailabilitySpec>>
126+
SemanticAvailabilitySpecRequest::getCachedResult() const {
127+
auto *spec = std::get<0>(getStorage());
128+
auto domainOrIdentifier = spec->getDomainOrIdentifier();
129+
if (!domainOrIdentifier.isResolved())
130+
return {};
131+
132+
if (spec->isInvalid())
133+
return {std::nullopt};
134+
135+
return SemanticAvailabilitySpec(spec);
136+
}
137+
138+
void SemanticAvailabilitySpecRequest::cacheResult(
139+
std::optional<SemanticAvailabilitySpec> value) const {
140+
auto *mutableSpec = const_cast<AvailabilitySpec *>(std::get<0>(getStorage()));
141+
if (!value)
142+
mutableSpec->setInvalid();
143+
}

0 commit comments

Comments
 (0)