Skip to content

Commit 6bfe518

Browse files
committed
AST: Compute FuncDecl::isStatic() using a request
1 parent 7063ecd commit 6bfe518

File tree

7 files changed

+69
-13
lines changed

7 files changed

+69
-13
lines changed

include/swift/AST/Decl.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,10 @@ class alignas(1 << DeclAlignInBits) Decl {
418418
HasSingleExpressionBody : 1
419419
);
420420

421-
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+2+1+1+2,
421+
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2,
422+
/// Whether we've computed the 'static' flag yet.
423+
IsStaticComputed : 1,
424+
422425
/// Whether this function is a 'static' method.
423426
IsStatic : 1,
424427

@@ -5960,6 +5963,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);
59605963
class FuncDecl : public AbstractFunctionDecl {
59615964
friend class AbstractFunctionDecl;
59625965
friend class SelfAccessKindRequest;
5966+
friend class IsStaticRequest;
59635967

59645968
SourceLoc StaticLoc; // Location of the 'static' token or invalid.
59655969
SourceLoc FuncLoc; // Location of the 'func' token.
@@ -5981,14 +5985,14 @@ class FuncDecl : public AbstractFunctionDecl {
59815985
StaticLoc(StaticLoc), FuncLoc(FuncLoc) {
59825986
assert(!Name.getBaseName().isSpecial());
59835987

5984-
Bits.FuncDecl.IsStatic =
5985-
StaticLoc.isValid() || StaticSpelling != StaticSpellingKind::None;
59865988
Bits.FuncDecl.StaticSpelling = static_cast<unsigned>(StaticSpelling);
59875989

59885990
Bits.FuncDecl.ForcedStaticDispatch = false;
59895991
Bits.FuncDecl.SelfAccess =
59905992
static_cast<unsigned>(SelfAccessKind::NonMutating);
59915993
Bits.FuncDecl.SelfAccessComputed = false;
5994+
Bits.FuncDecl.IsStaticComputed = false;
5995+
Bits.FuncDecl.IsStatic = false;
59925996
}
59935997

59945998
private:
@@ -6008,6 +6012,13 @@ class FuncDecl : public AbstractFunctionDecl {
60086012
return None;
60096013
}
60106014

6015+
Optional<bool> getCachedIsStatic() const {
6016+
if (Bits.FuncDecl.IsStaticComputed)
6017+
return Bits.FuncDecl.IsStatic;
6018+
6019+
return None;
6020+
}
6021+
60116022
public:
60126023
/// Factory function only for use by deserialization.
60136024
static FuncDecl *createDeserialized(ASTContext &Context, SourceLoc StaticLoc,
@@ -6030,16 +6041,16 @@ class FuncDecl : public AbstractFunctionDecl {
60306041

60316042
Identifier getName() const { return getFullName().getBaseIdentifier(); }
60326043

6033-
bool isStatic() const {
6034-
return Bits.FuncDecl.IsStatic;
6035-
}
6044+
bool isStatic() const;
6045+
60366046
/// \returns the way 'static'/'class' was spelled in the source.
60376047
StaticSpellingKind getStaticSpelling() const {
60386048
return static_cast<StaticSpellingKind>(Bits.FuncDecl.StaticSpelling);
60396049
}
60406050
/// \returns the way 'static'/'class' should be spelled for this declaration.
60416051
StaticSpellingKind getCorrectStaticSpelling() const;
60426052
void setStatic(bool IsStatic = true) {
6053+
Bits.FuncDecl.IsStaticComputed = true;
60436054
Bits.FuncDecl.IsStatic = IsStatic;
60446055
}
60456056

include/swift/AST/TypeCheckRequests.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,28 @@ class OpaqueResultTypeRequest
12921292
bool isCached() const { return true; }
12931293
};
12941294

1295+
/// Determines if a function declaration is 'static'.
1296+
class IsStaticRequest :
1297+
public SimpleRequest<IsStaticRequest,
1298+
bool(FuncDecl *),
1299+
CacheKind::SeparatelyCached> {
1300+
public:
1301+
using SimpleRequest::SimpleRequest;
1302+
1303+
private:
1304+
friend SimpleRequest;
1305+
1306+
// Evaluation.
1307+
llvm::Expected<bool>
1308+
evaluate(Evaluator &evaluator, FuncDecl *value) const;
1309+
1310+
public:
1311+
// Separate caching.
1312+
bool isCached() const { return true; }
1313+
Optional<bool> getCachedResult() const;
1314+
void cacheResult(bool value) const;
1315+
};
1316+
12951317
// Allow AnyValue to compare two Type values, even though Type doesn't
12961318
// support ==.
12971319
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,5 @@ SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *),
147147
Cached, NoLocationInfo)
148148
SWIFT_REQUEST(TypeChecker, IsABICompatibleOverrideRequest,
149149
bool(ValueDecl *), Cached, NoLocationInfo)
150+
SWIFT_REQUEST(TypeChecker, IsStaticRequest,
151+
bool(FuncDecl *), SeparatelyCached, NoLocationInfo)

lib/AST/ASTVerifier.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3190,12 +3190,6 @@ class Verifier : public ASTWalker {
31903190
void verifyParsed(AccessorDecl *FD) {
31913191
PrettyStackTraceDecl debugStack("verifying AccessorDecl", FD);
31923192

3193-
auto storage = FD->getStorage();
3194-
if (storage->isStatic() != FD->isStatic()) {
3195-
Out << "accessor static-ness must match static-ness of storage\n";
3196-
abort();
3197-
}
3198-
31993193
verifyParsedBase(FD);
32003194
}
32013195

lib/AST/Decl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6880,7 +6880,14 @@ OperatorDecl *FuncDecl::getOperatorDecl() const {
68806880
const_cast<FuncDecl *>(this)
68816881
},
68826882
nullptr);
6883-
}
6883+
}
6884+
6885+
bool FuncDecl::isStatic() const {
6886+
ASTContext &ctx = getASTContext();
6887+
return evaluateOrDefault(ctx.evaluator,
6888+
IsStaticRequest{const_cast<FuncDecl *>(this)},
6889+
false);
6890+
}
68846891

68856892
AccessorDecl *AccessorDecl::createImpl(ASTContext &ctx,
68866893
SourceLoc declLoc,

lib/AST/TypeCheckRequests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,3 +895,17 @@ void EnumRawValuesRequest::diagnoseCycle(DiagnosticEngine &diags) const {
895895
void EnumRawValuesRequest::noteCycleStep(DiagnosticEngine &diags) const {
896896

897897
}
898+
899+
//----------------------------------------------------------------------------//
900+
// IsStaticRequest computation.
901+
//----------------------------------------------------------------------------//
902+
903+
Optional<bool> IsStaticRequest::getCachedResult() const {
904+
auto *FD = std::get<0>(getStorage());
905+
return FD->getCachedIsStatic();
906+
}
907+
908+
void IsStaticRequest::cacheResult(bool result) const {
909+
auto *FD = std::get<0>(getStorage());
910+
FD->setStatic(result);
911+
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,12 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12381238
return false;
12391239
}
12401240

1241+
llvm::Expected<bool>
1242+
IsStaticRequest::evaluate(Evaluator &evaluator, FuncDecl *decl) const {
1243+
return (decl->getStaticLoc().isValid() ||
1244+
decl->getStaticSpelling() != StaticSpellingKind::None);
1245+
}
1246+
12411247
llvm::Expected<bool>
12421248
IsDynamicRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12431249
// If we can't infer dynamic here, don't.

0 commit comments

Comments
 (0)