Skip to content

Commit 70e7e84

Browse files
authored
Merge pull request #41348 from tshortli/emit-backdeploy-function-bodies
Emit function bodies for functions annotated with @_backDeploy
2 parents 827df01 + 2461313 commit 70e7e84

File tree

6 files changed

+57
-13
lines changed

6 files changed

+57
-13
lines changed

include/swift/AST/DeclContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ struct FragileFunctionKind {
201201
AlwaysEmitIntoClient,
202202
DefaultArgument,
203203
PropertyInitializer,
204+
BackDeploy,
204205
None
205206
};
206207

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ ResilienceExpansion DeclContext::getResilienceExpansion() const {
320320
case FragileFunctionKind::AlwaysEmitIntoClient:
321321
case FragileFunctionKind::DefaultArgument:
322322
case FragileFunctionKind::PropertyInitializer:
323+
case FragileFunctionKind::BackDeploy:
323324
return ResilienceExpansion::Minimal;
324325
case FragileFunctionKind::None:
325326
return ResilienceExpansion::Maximal;
@@ -418,6 +419,11 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
418419
/*allowUsableFromInline=*/true};
419420
}
420421

422+
if (AFD->getAttrs().hasAttribute<BackDeployAttr>()) {
423+
return {FragileFunctionKind::BackDeploy,
424+
/*allowUsableFromInline=*/true};
425+
}
426+
421427
// If a property or subscript is @inlinable or @_alwaysEmitIntoClient,
422428
// the accessors are @inlinable or @_alwaysEmitIntoClient also.
423429
if (auto accessor = dyn_cast<AccessorDecl>(AFD)) {

lib/AST/TypeCheckRequests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ void swift::simple_display(llvm::raw_ostream &out,
562562
case FragileFunctionKind::PropertyInitializer:
563563
out << "propertyInitializer";
564564
break;
565+
case FragileFunctionKind::BackDeploy:
566+
out << "backDeploy";
567+
break;
565568
case FragileFunctionKind::None:
566569
out << "none";
567570
break;

lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2927,7 +2927,8 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
29272927
StringRef AttrName = "@_backDeploy";
29282928
ParserStatus Status = parseList(tok::r_paren, LeftLoc, RightLoc, false,
29292929
diag::attr_back_deploy_missing_rparen,
2930-
SyntaxKind::Unknown, [&]() -> ParserStatus {
2930+
SyntaxKind::AvailabilitySpecList,
2931+
[&]() -> ParserStatus {
29312932
ParserStatus ListItemStatus =
29322933
parsePlatformVersionInList(AttrName, PlatformAndVersions);
29332934
if (ListItemStatus.isErrorOrHasCompletion())

test/ModuleInterface/back-deploy-attr.swift

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,24 @@
1717

1818
public struct TopLevelStruct {
1919
// CHECK: @_backDeploy(macOS 11.0)
20-
// CHECK: public func backDeployedFunc1_SinglePlatform() -> Swift.Int
20+
// FROMSOURCE: public func backDeployedFunc1_SinglePlatform() -> Swift.Int { return 42 }
21+
// FROMMODULE: public func backDeployedFunc1_SinglePlatform() -> Swift.Int
2122
@available(macOS 12.0, *)
2223
@_backDeploy(macOS 11.0)
23-
public func backDeployedFunc1_SinglePlatform() -> Int {
24-
return 42
25-
}
24+
public func backDeployedFunc1_SinglePlatform() -> Int { return 42 }
2625

2726
// CHECK: @_backDeploy(macOS 11.0)
2827
// CHECK: @_backDeploy(iOS 14.0)
29-
// CHECK: public func backDeployedFunc2_MultiPlatform() -> Swift.Int
28+
// FROMSOURCE: public func backDeployedFunc2_MultiPlatform() -> Swift.Int { return 43 }
29+
// FROMMODULE: public func backDeployedFunc2_MultiPlatform() -> Swift.Int
3030
@available(macOS 12.0, *)
3131
@_backDeploy(macOS 11.0, iOS 14.0)
32-
public func backDeployedFunc2_MultiPlatform() -> Int {
33-
return 43
34-
}
32+
public func backDeployedFunc2_MultiPlatform() -> Int { return 43 }
3533
}
3634

3735
// CHECK: @_backDeploy(macOS 11.0)
38-
// CHECK: public func backDeployTopLevelFunc() -> Swift.Int
36+
// FROMSOURCE: public func backDeployTopLevelFunc() -> Swift.Int { return 44 }
37+
// FROMMODULE: public func backDeployTopLevelFunc() -> Swift.Int
3938
@available(macOS 12.0, *)
4039
@_backDeploy(macOS 11.0)
41-
public func backDeployTopLevelFunc() -> Int {
42-
return 42
43-
}
40+
public func backDeployTopLevelFunc() -> Int { return 44 }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.50 | %FileCheck %s
3+
// RUN: %target-swift-emit-silgen %s -target %target-cpu-apple-macosx10.60 | %FileCheck %s
4+
// REQUIRES: OS=macosx
5+
6+
// CHECK-LABEL: sil [serialized] [available 10.51] [ossa] @$s21back_deploy_attribute0A12DeployedFuncyyF : $@convention(thin) () -> ()
7+
@available(macOS 10.51, *)
8+
@_backDeploy(macOS 10.50)
9+
public func backDeployedFunc() {}
10+
11+
@available(macOS 10.50, *)
12+
public struct TopLevelStruct {
13+
// CHECK-LABEL: sil [serialized] [available 10.51] [ossa] @$s21back_deploy_attribute14TopLevelStructV0a8DeployedF4FuncyyF : $@convention(method) (TopLevelStruct) -> ()
14+
@available(macOS 10.51, *)
15+
@_backDeploy(macOS 10.50)
16+
public func backDeployedStructFunc() {}
17+
}
18+
19+
20+
// FIXME(backDeploy): Verify SIL in a caller that requires back deployment
21+
22+
23+
// CHECK-LABLEL: sil hidden [available 10.51] [ossa] @$s21back_deploy_attribute21alwaysAvailableCalleryyAA14TopLevelStructVF : $@convention(thin) (TopLevelStruct) -> ()
24+
// CHECK: bb0(%0 : $TopLevelStruct):
25+
@available(macOS 10.51, *)
26+
func alwaysAvailableCaller(_ s: TopLevelStruct) {
27+
/// This function's availability meets the minimum availability of the APIs, so
28+
/// no back deployment logic is required.
29+
30+
// CHECK: %2 = function_ref @$s21back_deploy_attribute0A12DeployedFuncyyF : $@convention(thin) () -> ()
31+
// CHECK: %3 = apply %2() : $@convention(thin) () -> ()
32+
backDeployedFunc()
33+
// CHECK: %4 = function_ref @$s21back_deploy_attribute14TopLevelStructV0a8DeployedF4FuncyyF : $@convention(method) (TopLevelStruct) -> ()
34+
// CHECK: %5 = apply %4(%0) : $@convention(method) (TopLevelStruct) -> ()
35+
s.backDeployedStructFunc()
36+
}

0 commit comments

Comments
 (0)