Skip to content

Commit 37afa7c

Browse files
author
David Ungar
authored
Merge pull request swiftlang#27435 from davidungar/A-9-29-recursion-assert
[ASTScopes] Use RequestEvaluator for ASTScope expansion to detect recursion
2 parents 73df6cf + 571d815 commit 37afa7c

File tree

7 files changed

+189
-95
lines changed

7 files changed

+189
-95
lines changed

include/swift/AST/ASTScope.h

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "swift/AST/ASTNode.h"
3232
#include "swift/AST/NameLookup.h" // for DeclVisibilityKind
33+
#include "swift/AST/SimpleRequest.h"
3334
#include "swift/Basic/Compiler.h"
3435
#include "swift/Basic/LLVM.h"
3536
#include "swift/Basic/NullablePtr.h"
@@ -88,6 +89,14 @@ struct AnnotatedInsertionPoint {
8889
ASTScopeImpl *insertionPoint;
8990
const char *explanation;
9091
};
92+
} // namespace ast_scope
93+
94+
namespace ast_scope {
95+
96+
void simple_display(llvm::raw_ostream &out, const ASTScopeImpl *);
97+
void simple_display(llvm::raw_ostream &out, const ScopeCreator *);
98+
99+
SourceLoc extractNearestSourceLoc(std::tuple<ASTScopeImpl *, ScopeCreator *>);
91100

92101
#pragma mark the root ASTScopeImpl class
93102

@@ -333,6 +342,11 @@ class ASTScopeImpl {
333342
public:
334343
/// expandScope me, sending deferred nodes to my descendants.
335344
/// Return the scope into which to place subsequent decls
345+
ASTScopeImpl *expandAndBeCurrentDetectingRecursion(ScopeCreator &);
346+
347+
/// Expand or reexpand the scope if unexpanded or if not current.
348+
/// There are several places in the compiler that mutate the AST after the
349+
/// fact, above and beyond adding Decls to the SourceFile.
336350
ASTScopeImpl *expandAndBeCurrent(ScopeCreator &);
337351

338352
unsigned getASTAncestorScopeCount() const { return astAncestorScopeCount; }
@@ -344,6 +358,12 @@ class ASTScopeImpl {
344358
void setWasExpanded() { wasExpanded = true; }
345359
virtual ASTScopeImpl *expandSpecifically(ScopeCreator &) = 0;
346360
virtual void beCurrent();
361+
virtual bool doesExpansionOnlyAddNewDeclsAtEnd() const;
362+
363+
public:
364+
bool isExpansionNeeded(const ScopeCreator &) const;
365+
366+
protected:
347367
bool isCurrent() const;
348368
virtual bool isCurrentIfWasExpanded() const;
349369

@@ -374,16 +394,7 @@ class ASTScopeImpl {
374394

375395
bool isATypeDeclScope() const;
376396

377-
/// There are several places in the compiler that mutate the AST after the
378-
/// fact, above and beyond adding Decls to the SourceFile. These are
379-
/// documented in: rdar://53018839, rdar://53027266, rdar://53027733,
380-
/// rdar://53028050
381-
/// Return true if did reexpand
382-
bool reexpandIfObsolete(ScopeCreator &);
383-
384397
private:
385-
void reexpand(ScopeCreator &);
386-
387398
virtual ScopeCreator &getScopeCreator();
388399

389400
#pragma mark - - creation queries
@@ -533,8 +544,8 @@ class ASTSourceFileScope final : public ASTScopeImpl {
533544
/// The number of \c Decls in the \c SourceFile that were already seen.
534545
/// Since parsing can be interleaved with type-checking, on every
535546
/// lookup, look at creating scopes for any \c Decls beyond this number.
536-
/// rdar://55562483 Unify with numberOfChildrenWhenLastExpanded
537-
int numberOfDeclsAlreadySeen = 0;
547+
/// TODO: Unify with numberOfChildrenWhenLastExpanded
548+
size_t numberOfDeclsAlreadySeen = 0;
538549

539550
ASTSourceFileScope(SourceFile *SF, ScopeCreator *scopeCreator);
540551

@@ -548,7 +559,6 @@ class ASTSourceFileScope final : public ASTScopeImpl {
548559
public:
549560
NullablePtr<DeclContext> getDeclContext() const override;
550561

551-
void addNewDeclsToScopeTree();
552562
void buildFullyExpandedTree();
553563
void
554564
buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
@@ -559,11 +569,15 @@ class ASTSourceFileScope final : public ASTScopeImpl {
559569

560570
protected:
561571
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
572+
bool isCurrentIfWasExpanded() const override;
573+
void beCurrent() override;
574+
bool doesExpansionOnlyAddNewDeclsAtEnd() const override;
562575

563576
ScopeCreator &getScopeCreator() override;
564577

565578
private:
566-
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
579+
AnnotatedInsertionPoint
580+
expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);
567581
};
568582

569583
class Portion {
@@ -1148,7 +1162,6 @@ class AttachedPropertyWrapperScope final : public ASTScopeImpl {
11481162
/// false positives, that that doesn't hurt anything. However, the result of
11491163
/// the conservative source range computation doesn't seem to be stable. So
11501164
/// keep the original here, and use it for source range queries.
1151-
/// rdar://55263708
11521165

11531166
const SourceRange sourceRangeWhenCreated;
11541167

@@ -1251,7 +1264,6 @@ class PatternEntryDeclScope final : public AbstractPatternEntryScope {
12511264
};
12521265

12531266
class PatternEntryInitializerScope final : public AbstractPatternEntryScope {
1254-
// Should be able to remove this when rdar://53921703 is accomplished.
12551267
Expr *initAsWrittenWhenCreated;
12561268

12571269
public:

include/swift/AST/NameLookupRequests.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class GenericContext;
3030
class GenericParamList;
3131
class TypeAliasDecl;
3232
class TypeDecl;
33+
namespace ast_scope {
34+
class ASTScopeImpl;
35+
class ScopeCreator;
36+
} // namespace ast_scope
3337

3438
/// Display a nominal type or extension thereof.
3539
void simple_display(
@@ -324,6 +328,30 @@ class LookupPrecedenceGroupRequest
324328
bool isCached() const { return true; }
325329
};
326330

331+
/// Expand the given ASTScope. Requestified to detect recursion.
332+
class ExpandASTScopeRequest
333+
: public SimpleRequest<ExpandASTScopeRequest,
334+
ast_scope::ASTScopeImpl *(ast_scope::ASTScopeImpl *,
335+
ast_scope::ScopeCreator *),
336+
CacheKind::SeparatelyCached> {
337+
public:
338+
using SimpleRequest::SimpleRequest;
339+
340+
private:
341+
friend SimpleRequest;
342+
343+
// Evaluation.
344+
llvm::Expected<ast_scope::ASTScopeImpl *>
345+
evaluate(Evaluator &evaluator, ast_scope::ASTScopeImpl *,
346+
ast_scope::ScopeCreator *) const;
347+
348+
public:
349+
// Separate caching.
350+
bool isCached() const;
351+
Optional<ast_scope::ASTScopeImpl *> getCachedResult() const;
352+
void cacheResult(ast_scope::ASTScopeImpl *) const {}
353+
};
354+
327355
#define SWIFT_TYPEID_ZONE NameLookup
328356
#define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
329357
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest,
1919
NominalTypeDecl *(CustomAttr *, DeclContext *), Cached,
2020
NoLocationInfo)
21+
SWIFT_REQUEST(NameLookup, ExpandASTScopeRequest,
22+
ast_scope::ASTScopeImpl* (ast_scope::ASTScopeImpl*, ast_scope::ScopeCreator*),
23+
SeparatelyCached,
24+
NoLocationInfo)
2125
SWIFT_REQUEST(NameLookup, ExtendedNominalRequest,
2226
NominalTypeDecl *(ExtensionDecl *), SeparatelyCached,
2327
NoLocationInfo)

0 commit comments

Comments
 (0)