Add AST briding

This commit is contained in:
Freddy Kellison-Linn
2025-09-01 17:59:04 -04:00
parent e7d62c8059
commit 1996da87cb
7 changed files with 38 additions and 13 deletions

View File

@@ -2325,6 +2325,9 @@ BridgedBraceStmt BridgedBraceStmt_createImplicit(BridgedASTContext cContext,
BridgedASTNode element,
swift::SourceLoc rBLoc);
SWIFT_NAME("BridgedBraceStmt.hasAsyncNode(self:)")
bool BridgedBraceStmt_hasAsyncNode(BridgedBraceStmt braceStmt);
SWIFT_NAME("BridgedBreakStmt.createParsed(_:loc:targetName:targetLoc:)")
BridgedBreakStmt BridgedBreakStmt_createParsed(BridgedDeclContext cDeclContext,
swift::SourceLoc loc,
@@ -2356,6 +2359,10 @@ BridgedDeferStmt BridgedDeferStmt_createParsed(BridgedDeclContext cDeclContext,
SWIFT_NAME("getter:BridgedDeferStmt.tempDecl(self:)")
BridgedFuncDecl BridgedDeferStmt_getTempDecl(BridgedDeferStmt bridged);
SWIFT_NAME("BridgedDeferStmt.makeAsync(self:_:)")
void BridgedDeferStmt_makeAsync(BridgedDeferStmt bridged,
BridgedASTContext ctx);
SWIFT_NAME("BridgedDiscardStmt.createParsed(_:discardLoc:subExpr:)")
BridgedDiscardStmt BridgedDiscardStmt_createParsed(BridgedASTContext cContext,
swift::SourceLoc discardLoc,

View File

@@ -424,7 +424,11 @@ public:
/// Dig the original user's body of the defer out for AST fidelity.
BraceStmt *getBodyAsWritten() const;
/// Turn this into an async defer by modifying the temp decl and call expr
/// appropriately.
void makeAsync(ASTContext &ctx);
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Defer; }
};

View File

@@ -96,6 +96,10 @@ BridgedBraceStmt BridgedBraceStmt_createImplicit(BridgedASTContext cContext,
/*Implicit=*/true);
}
bool BridgedBraceStmt_hasAsyncNode(BridgedBraceStmt braceStmt) {
return (bool)braceStmt.unbridged()->findAsyncNode();
}
BridgedBreakStmt BridgedBreakStmt_createParsed(BridgedDeclContext cDeclContext,
SourceLoc loc,
Identifier targetName,
@@ -156,6 +160,11 @@ BridgedFuncDecl BridgedDeferStmt_getTempDecl(BridgedDeferStmt bridged) {
return bridged.unbridged()->getTempDecl();
}
void BridgedDeferStmt_makeAsync(BridgedDeferStmt bridged,
BridgedASTContext ctx) {
return bridged.unbridged()->makeAsync(ctx.unbridged());
}
BridgedDiscardStmt BridgedDiscardStmt_createParsed(BridgedASTContext cContext,
SourceLoc discardLoc,
BridgedExpr cSubExpr) {

View File

@@ -401,6 +401,15 @@ BraceStmt *DeferStmt::getBodyAsWritten() const {
return tempDecl->getBody();
}
void DeferStmt::makeAsync(ASTContext &ctx) {
tempDecl->setHasAsync(true);
setCallExpr(AwaitExpr::createImplicit(ctx, SourceLoc(), getCallExpr()));
auto *attr = new (ctx) NonisolatedAttr(SourceLoc(), SourceRange(),
NonIsolatedModifier::NonSending,
/*implicit*/ true);
tempDecl->getAttrs().add(attr);
}
bool LabeledStmt::isPossibleContinueTarget() const {
switch (getKind()) {
#define LABELED_STMT(ID, PARENT)

View File

@@ -277,7 +277,11 @@ extension ASTGenVisitor {
deferLoc: deferLoc
)
self.withDeclContext(stmt.tempDecl.asDeclContext) {
stmt.tempDecl.setParsedBody(self.generate(codeBlock: node.body))
let body = self.generate(codeBlock: node.body)
stmt.tempDecl.setParsedBody(body)
if body.hasAsyncNode() {
stmt.makeAsync(ctx)
}
}
return stmt
}

View File

@@ -1097,16 +1097,8 @@ ParserResult<Stmt> Parser::parseStmtDefer() {
return nullptr;
Status |= Body;
bool isAsync = (bool)Body.get()->findAsyncNode();
tempDecl->setHasAsync(isAsync);
if (DS->getTempDecl()->isAsync()) {
DS->setCallExpr(AwaitExpr::createImplicit(Context, SourceLoc(),
DS->getCallExpr()));
auto *attr =
new (Context) NonisolatedAttr(SourceLoc(), SourceRange(),
NonIsolatedModifier::NonSending,
/*implicit*/ true);
tempDecl->getAttrs().add(attr);
if (bool(Body.get()->findAsyncNode())) {
DS->makeAsync(Context);
}
// Clone the current hasher and extract a Fingerprint.

View File

@@ -3469,7 +3469,7 @@ public:
// check this before we check `isImplicit` below since these are always
// implicit!
if (auto *applyExpr = dyn_cast_or_null<ApplyExpr>(node.dyn_cast<Expr*>())) {
auto *calledDecl = applyExpr->getCalledValue();
auto *calledDecl = applyExpr->getCalledValue(/*skipConversions=*/true);
if (auto *fnDecl = dyn_cast_or_null<FuncDecl>(calledDecl)) {
if (fnDecl->isDeferBody()) {
Diags.diagnose(fnDecl->getStartLoc(),