Skip to content

Commit 1291333

Browse files
committed
ASTGen: Cache parsed IterableDeclContext members using the request evaluator
...instead of adding them to the iterable context lest they be re-parsed using the legacy parser and later re-added through `IterableDeclContext::loadAllMembers`.
1 parent a141fba commit 1291333

File tree

4 files changed

+48
-41
lines changed

4 files changed

+48
-41
lines changed

include/swift/AST/CASTBridging.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,8 @@ typedef struct BridgedFuncDecl {
202202
} BridgedFuncDecl;
203203

204204
typedef struct BridgedDeclContextAndDecl {
205-
BridgedDeclContext declContext;
206-
void *nominalDecl;
207-
void *decl;
205+
BridgedDeclContext asDeclContext;
206+
void *asDecl;
208207
} BridgedDeclContextAndDecl;
209208

210209
typedef struct BridgedTypeAttributes {
@@ -338,7 +337,8 @@ void *TypeAliasDecl_create(
338337
BridgedSourceLoc cNameLoc, void *_Nullable opaqueGenericParamList,
339338
BridgedSourceLoc cEqualLoc, void *opaqueUnderlyingType);
340339

341-
void NominalTypeDecl_setMembers(void *decl, BridgedArrayRef members);
340+
void IterableDeclContext_setParsedMembers(BridgedArrayRef members,
341+
void *opaqueDecl);
342342

343343
BridgedDeclContextAndDecl
344344
StructDecl_create(BridgedASTContext cContext, BridgedDeclContext cDeclContext,

lib/AST/CASTBridging.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "swift/AST/GenericParamList.h"
99
#include "swift/AST/Identifier.h"
1010
#include "swift/AST/ParameterList.h"
11+
#include "swift/AST/ParseRequests.h"
1112
#include "swift/AST/Pattern.h"
1213
#include "swift/AST/PluginRegistry.h"
1314
#include "swift/AST/Stmt.h"
@@ -517,10 +518,15 @@ void *TypeAliasDecl_create(
517518
return static_cast<Decl *>(decl);
518519
}
519520

520-
void NominalTypeDecl_setMembers(void *decl, BridgedArrayRef members) {
521-
auto declMembers = convertArrayRef<Decl *>(members);
522-
for (auto m : declMembers)
523-
((NominalTypeDecl *)decl)->addMember(m);
521+
void IterableDeclContext_setParsedMembers(BridgedArrayRef bridgedMembers,
522+
void *opaqueDecl) {
523+
auto *decl = static_cast<Decl *>(opaqueDecl);
524+
auto &ctx = decl->getASTContext();
525+
auto members = convertArrayRef<Decl *>(bridgedMembers);
526+
527+
ctx.evaluator.cacheOutput(
528+
ParseMembersRequest{cast<IterableDeclContext>(decl)},
529+
FingerprintAndMembers{llvm::None, ctx.AllocateCopy(members)});
524530
}
525531

526532
BridgedDeclContextAndDecl
@@ -530,14 +536,13 @@ StructDecl_create(BridgedASTContext cContext, BridgedDeclContext cDeclContext,
530536
void *_Nullable opaqueGenericParamList) {
531537
ASTContext &context = convertASTContext(cContext);
532538

533-
auto *out = new (context)
539+
auto *decl = new (context)
534540
StructDecl(convertSourceLoc(cStructKeywordLoc), convertIdentifier(cName),
535541
convertSourceLoc(cNameLoc), {},
536542
static_cast<GenericParamList *>(opaqueGenericParamList),
537543
convertDeclContext(cDeclContext));
538544

539-
return {bridgeDeclContext(out), static_cast<NominalTypeDecl *>(out),
540-
static_cast<Decl *>(out)};
545+
return {bridgeDeclContext(decl), static_cast<Decl *>(decl)};
541546
}
542547

543548
BridgedDeclContextAndDecl ClassDecl_create(BridgedASTContext cContext,
@@ -547,13 +552,12 @@ BridgedDeclContextAndDecl ClassDecl_create(BridgedASTContext cContext,
547552
BridgedSourceLoc cNameLoc) {
548553
ASTContext &context = convertASTContext(cContext);
549554

550-
auto *out = new (context)
555+
auto *decl = new (context)
551556
ClassDecl(convertSourceLoc(cClassKeywordLoc), convertIdentifier(cName),
552557
convertSourceLoc(cNameLoc), {}, nullptr,
553558
convertDeclContext(cDeclContext), false);
554559

555-
return {bridgeDeclContext(out), static_cast<NominalTypeDecl *>(out),
556-
static_cast<Decl *>(out)};
560+
return {bridgeDeclContext(decl), static_cast<Decl *>(decl)};
557561
}
558562

559563
void *OptionalTypeRepr_create(BridgedASTContext cContext, void *base,

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
6868

6969
let base: UnsafeBufferPointer<UInt8>
7070

71-
@Boxed var declContext: BridgedDeclContext
71+
@Boxed private(set) var declContext: BridgedDeclContext
7272

7373
let ctx: BridgedASTContext
7474

@@ -123,6 +123,17 @@ struct ASTGenVisitor: SyntaxTransformVisitor {
123123
}
124124
}
125125

126+
extension ASTGenVisitor {
127+
/// Replaces the current declaration context with `declContext` for the duration of its execution, and calls `body`.
128+
@inline(__always)
129+
func withDeclContext(_ declContext: BridgedDeclContext, _ body: () -> Void) {
130+
let oldDeclContext = self.declContext
131+
self.declContext = declContext
132+
body()
133+
self.declContext = oldDeclContext
134+
}
135+
}
136+
126137
extension ASTGenVisitor {
127138
/// Emits the given diagnostic via the C++ diagnostic engine.
128139
@inline(__always)

lib/ASTGen/Sources/ASTGen/Decls.swift

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import CASTBridging
44
@_spi(SyntaxTransformVisitor)
55
import SwiftSyntax
66

7+
// MARK: - TypeDecl
8+
79
extension ASTGenVisitor {
810
public func visit(_ node: TypeAliasDeclSyntax) -> ASTNode {
911
let (name, nameLoc) = node.name.bridgedIdentifierAndSourceLoc(in: self)
@@ -25,7 +27,7 @@ extension ASTGenVisitor {
2527
public func visit(_ node: StructDeclSyntax) -> ASTNode {
2628
let (name, nameLoc) = node.name.bridgedIdentifierAndSourceLoc(in: self)
2729

28-
let out = StructDecl_create(
30+
let decl = StructDecl_create(
2931
self.ctx,
3032
self.declContext,
3133
self.bridgedSourceLoc(for: node.structKeyword),
@@ -34,34 +36,33 @@ extension ASTGenVisitor {
3436
self.visit(node.genericParameterClause)?.rawValue
3537
)
3638

37-
let oldDeclContext = declContext
38-
declContext = out.declContext
39-
defer { declContext = oldDeclContext }
40-
41-
NominalTypeDecl_setMembers(out.nominalDecl, self.visit(node.memberBlock.members))
39+
self.withDeclContext(decl.asDeclContext) {
40+
IterableDeclContext_setParsedMembers(self.visit(node.memberBlock.members), decl.asDecl)
41+
}
4242

43-
return .decl(out.decl)
43+
return .decl(decl.asDecl)
4444
}
4545

4646
public func visit(_ node: ClassDeclSyntax) -> ASTNode {
4747
let (name, nameLoc) = node.name.bridgedIdentifierAndSourceLoc(in: self)
4848

49-
let out = ClassDecl_create(
49+
let decl = ClassDecl_create(
5050
self.ctx,
5151
self.declContext,
5252
self.bridgedSourceLoc(for: node.classKeyword),
5353
name,
5454
nameLoc
5555
)
56-
let oldDeclContext = declContext
57-
declContext = out.declContext
58-
defer { declContext = oldDeclContext }
5956

60-
NominalTypeDecl_setMembers(out.nominalDecl, self.visit(node.memberBlock.members))
57+
self.withDeclContext(decl.asDeclContext) {
58+
IterableDeclContext_setParsedMembers(self.visit(node.memberBlock.members), decl.asDecl)
59+
}
6160

62-
return .decl(out.decl)
61+
return .decl(decl.asDecl)
6362
}
63+
}
6464

65+
extension ASTGenVisitor {
6566
public func visit(_ node: VariableDeclSyntax) -> ASTNode {
6667
let pattern = visit(node.bindings.first!.pattern).rawValue
6768
let initializer = visit(node.bindings.first!.initializer!).rawValue
@@ -131,19 +132,10 @@ extension ASTGenVisitor {
131132
self.visit(node.signature.returnClause?.type)?.rawValue
132133
)
133134

134-
let oldDeclContext = declContext
135-
declContext = out.declContext
136-
defer { declContext = oldDeclContext }
137-
138-
let body: ASTNode?
139-
if let nodeBody = node.body {
140-
body = visit(nodeBody)
141-
} else {
142-
body = nil
143-
}
144-
145-
if let body = body {
146-
FuncDecl_setBody(out.funcDecl, body.rawValue)
135+
if let body = node.body {
136+
self.withDeclContext(out.declContext) {
137+
FuncDecl_setBody(out.funcDecl, self.visit(body).rawValue)
138+
}
147139
}
148140

149141
return .decl(out.decl)

0 commit comments

Comments
 (0)