Skip to content

Commit 6184367

Browse files
committed
[Parse] Post-process parsed AST to register decls with opaque result
Move the logic out of `Paser` so `ASTGen` can use it.
1 parent 214315b commit 6184367

File tree

5 files changed

+95
-34
lines changed

5 files changed

+95
-34
lines changed

include/swift/AST/ASTBridgingImpl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ BridgedASTContext BridgedASTContext_fromRaw(void * _Nonnull ptr) {
107107
return *static_cast<swift::ASTContext *>(ptr);
108108
}
109109

110-
BRIDGED_INLINE
111110
void *_Nullable BridgedASTContext_allocate(BridgedASTContext bridged,
112111
size_t size, size_t alignment) {
113112
return bridged.unbridged().Allocate(size, alignment);
@@ -157,7 +156,7 @@ BridgedDeclContext_getParentSourceFile(BridgedDeclContext dc) {
157156
// MARK: BridgedSoureFile
158157
//===----------------------------------------------------------------------===//
159158

160-
BRIDGED_INLINE bool BridgedSourceFile_isScriptMode(BridgedSourceFile sf) {
159+
bool BridgedSourceFile_isScriptMode(BridgedSourceFile sf) {
161160
return sf.unbridged()->isScriptMode();
162161
}
163162

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,15 +2037,15 @@ namespace {
20372037
void visitTypeAliasDecl(TypeAliasDecl *TAD, Label label) {
20382038
printCommon(TAD, "typealias", label);
20392039

2040-
printWhereRequirements(TAD);
2041-
printAttributes(TAD);
2042-
20432040
if (auto underlying = TAD->getCachedUnderlyingType()) {
20442041
printTypeField(underlying, Label::always("type"));
20452042
} else {
20462043
printRec(TAD->getUnderlyingTypeRepr(), Label::always("type_repr"));
20472044
}
20482045

2046+
printWhereRequirements(TAD);
2047+
printAttributes(TAD);
2048+
20492049
printFoot();
20502050
}
20512051

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8491,24 +8491,14 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
84918491

84928492
pattern = patternRes.get();
84938493
}
8494-
8495-
bool hasOpaqueReturnTy = false;
8496-
if (auto typedPattern = dyn_cast<TypedPattern>(pattern)) {
8497-
hasOpaqueReturnTy = typedPattern->getTypeRepr()->hasOpaque();
8498-
}
8499-
auto sf = CurDeclContext->getOutermostParentSourceFile();
8500-
8494+
85018495
// Configure all vars with attributes, 'static' and parent pattern.
85028496
pattern->forEachVariable([&](VarDecl *VD) {
85038497
VD->setStatic(StaticLoc.isValid());
85048498
VD->attachParsedAttrs(Attributes);
85058499
VD->setTopLevelGlobal(topLevelDecl);
85068500

85078501
Decls.push_back(VD);
8508-
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment
8509-
&& !InFreestandingMacroArgument) {
8510-
sf->addUnvalidatedDeclWithOpaqueResultType(VD);
8511-
}
85128502
});
85138503

85148504
// Remember this pattern/init pair for our ultimate PatternBindingDecl. The
@@ -8788,14 +8778,6 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
87888778
BodyParams, FuncRetTy,
87898779
CurDeclContext);
87908780

8791-
// Let the source file track the opaque return type mapping, if any.
8792-
if (FuncRetTy && FuncRetTy->hasOpaque() &&
8793-
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
8794-
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
8795-
sf->addUnvalidatedDeclWithOpaqueResultType(FD);
8796-
}
8797-
}
8798-
87998781
// Parse a 'where' clause if present.
88008782
if (Tok.is(tok::kw_where)) {
88018783
ContextChange CC(*this, FD);
@@ -9682,14 +9664,6 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
96829664
Context, StaticLoc, StaticSpelling, SubscriptLoc, Indices.get(), ArrowLoc,
96839665
ElementTy.get(), CurDeclContext, GenericParams);
96849666
Subscript->attachParsedAttrs(Attributes);
9685-
9686-
// Let the source file track the opaque return type mapping, if any.
9687-
if (ElementTy.get() && ElementTy.get()->hasOpaque() &&
9688-
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
9689-
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
9690-
sf->addUnvalidatedDeclWithOpaqueResultType(Subscript);
9691-
}
9692-
}
96939667

96949668
DefaultArgs.setFunctionContext(Subscript, Subscript->getIndices());
96959669

lib/Parse/ParseRequests.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
//===----------------------------------------------------------------------===//
1616
#include "swift/AST/ParseRequests.h"
1717
#include "swift/AST/ASTContext.h"
18+
#include "swift/AST/ASTWalker.h"
1819
#include "swift/AST/AvailabilitySpec.h"
1920
#include "swift/AST/Decl.h"
2021
#include "swift/AST/DeclContext.h"
2122
#include "swift/AST/Module.h"
2223
#include "swift/AST/SourceFile.h"
24+
#include "swift/AST/TypeRepr.h"
2325
#include "swift/Basic/Assertions.h"
2426
#include "swift/Basic/Defer.h"
2527
#include "swift/Bridging/ASTGen.h"
@@ -47,6 +49,82 @@ void swift::simple_display(llvm::raw_ostream &out,
4749
simple_display(out, value.members);
4850
}
4951

52+
namespace {
53+
54+
/// Find 'ValueDecl' with opaque type results and let \p SF track the opaque
55+
/// return type mapping.
56+
// FIXME: This should be done in Sema or AST?
57+
class OpaqueResultCollector : public ASTWalker {
58+
SourceFile &SF;
59+
60+
public:
61+
OpaqueResultCollector(SourceFile &SF) : SF(SF) {}
62+
63+
void handle(ValueDecl *VD) const {
64+
TypeRepr *tyR = nullptr;
65+
if (auto *FD = dyn_cast<FuncDecl>(VD)) {
66+
if (isa<AccessorDecl>(VD))
67+
return;
68+
tyR = FD->getResultTypeRepr();
69+
} else if (auto *VarD = dyn_cast<VarDecl>(VD)) {
70+
if (!VarD->getParentPatternBinding())
71+
return;
72+
tyR = VarD->getTypeReprOrParentPatternTypeRepr();
73+
} else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
74+
tyR = SD->getElementTypeRepr();
75+
}
76+
77+
if (!tyR || !tyR->hasOpaque())
78+
return;
79+
80+
SF.addUnvalidatedDeclWithOpaqueResultType(VD);
81+
}
82+
83+
PreWalkAction walkToDeclPre(Decl *D) override {
84+
if (auto *VD = dyn_cast<ValueDecl>(D))
85+
handle(VD);
86+
87+
if (auto *IDC = dyn_cast<IterableDeclContext>(D)) {
88+
// Only walk into cached parsed members to avoid invoking lazy parsing.
89+
ParseMembersRequest req(IDC);
90+
if (SF.getASTContext().evaluator.hasCachedResult(req)) {
91+
auto memberResult = evaluateOrFatal(SF.getASTContext().evaluator, req);
92+
for (auto *D : memberResult.members)
93+
D->walk(*this);
94+
}
95+
return Action::SkipChildren();
96+
}
97+
98+
return Action::Continue();
99+
}
100+
101+
MacroWalking getMacroWalkingBehavior() const override {
102+
return MacroWalking::None;
103+
}
104+
105+
PreWalkAction walkToTypeReprPre(TypeRepr *T) override {
106+
return Action::SkipNode();
107+
}
108+
};
109+
110+
void registerDeclWithOpaqueResultType(SourceFile *SF, ArrayRef<ASTNode> items) {
111+
if (!SF)
112+
return;
113+
OpaqueResultCollector walker(*SF);
114+
for (const ASTNode &item : items)
115+
const_cast<ASTNode &>(item).walk(walker);
116+
}
117+
118+
void registerDeclWithOpaqueResultType(SourceFile *SF, ArrayRef<Decl *> items) {
119+
if (!SF)
120+
return;
121+
OpaqueResultCollector walker(*SF);
122+
for (Decl *item : items)
123+
item->walk(walker);
124+
}
125+
126+
} // namespace
127+
50128
FingerprintAndMembers
51129
ParseMembersRequest::evaluate(Evaluator &evaluator,
52130
IterableDeclContext *idc) const {
@@ -82,6 +160,9 @@ ParseMembersRequest::evaluate(Evaluator &evaluator,
82160
auto declsAndHash = parser.parseDeclListDelayed(idc);
83161
FingerprintAndMembers fingerprintAndMembers = {declsAndHash.second,
84162
declsAndHash.first};
163+
164+
registerDeclWithOpaqueResultType(sf->getOutermostParentSourceFile(),
165+
fingerprintAndMembers.members);
85166
return FingerprintAndMembers{
86167
fingerprintAndMembers.fingerprint,
87168
ctx.AllocateCopy(llvm::ArrayRef(fingerprintAndMembers.members))};
@@ -134,6 +215,8 @@ ParseAbstractFunctionBodyRequest::evaluate(Evaluator &evaluator,
134215
Parser parser(bufferID, *sf, /*SIL*/ nullptr);
135216
auto result = parser.parseAbstractFunctionBodyDelayed(afd);
136217
afd->setBodyKind(BodyKind::Parsed);
218+
registerDeclWithOpaqueResultType(afd->getOutermostParentSourceFile(),
219+
result.getBody()->getElements());
137220
return result;
138221
}
139222
}
@@ -312,6 +395,9 @@ SourceFileParsingResult parseSourceFileViaASTGen(SourceFile &SF) {
312395
fp = swift_ASTGen_getSourceFileFingerprint(exportedSourceFile, Ctx)
313396
.unbridged();
314397

398+
registerDeclWithOpaqueResultType(declContext->getOutermostParentSourceFile(),
399+
items);
400+
315401
return SourceFileParsingResult{/*TopLevelItems=*/Ctx.AllocateCopy(items),
316402
/*CollectedTokens=*/std::nullopt,
317403
/*Fingerprint=*/fp};
@@ -444,6 +530,9 @@ SourceFileParsingResult parseSourceFile(SourceFile &SF) {
444530
if (parser.CurrentTokenHash)
445531
fp = Fingerprint(std::move(*parser.CurrentTokenHash));
446532

533+
registerDeclWithOpaqueResultType(
534+
parser.CurDeclContext->getOutermostParentSourceFile(), items);
535+
447536
return SourceFileParsingResult{ctx.AllocateCopy(items), tokensRef, fp};
448537
}
449538

test/ASTGen/attrs.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,5 @@ protocol OpProto {}
199199
struct OpStruct: OpProto {}
200200
struct OpTest {
201201
func opResult() -> some OpProto { OpStruct() }
202-
// FIXME: Implement SF->addUnvalidatedDeclWithOpaqueResultType() in ASTGen
203-
// typealias Result = @_opaqueReturnTypeOf("$s6ASTGen6OpTestV8opResultQryF", 0) __
202+
typealias Result = @_opaqueReturnTypeOf("$s6ASTGen6OpTestV8opResultQryF", 0) __
204203
}

0 commit comments

Comments
 (0)