Skip to content

Commit be7462e

Browse files
authored
Merge pull request swiftlang#35413 from xymus/originally-defined-in-macro
[Sema] Accept availability macros in @_originallyDefinedIn
2 parents 58f7a10 + 8992d2c commit be7462e

File tree

9 files changed

+106
-8
lines changed

9 files changed

+106
-8
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ SIMPLE_DECL_ATTR(IBSegueAction, IBSegueAction,
534534

535535
DECL_ATTR(_originallyDefinedIn, OriginallyDefinedIn,
536536
OnNominalType | OnFunc | OnVar | OnExtension | UserInaccessible |
537-
AllowMultipleAttributes |
537+
AllowMultipleAttributes | LongAttribute |
538538
ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,
539539
96)
540540

include/swift/AST/AvailabilitySpec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
201201
: AvailabilitySpec(AvailabilitySpecKind::OtherPlatform),
202202
StarLoc(StarLoc) {}
203203

204+
SourceLoc getStarLoc() const { return StarLoc; }
205+
204206
SourceRange getSourceRange() const { return SourceRange(StarLoc, StarLoc); }
205207

206208
void print(raw_ostream &OS, unsigned Indent) const;

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,14 @@ WARNING(originally_defined_in_major_minor_only,none,
14891489
WARNING(originally_defined_in_missing_platform_name,none,
14901490
"* as platform name has no effect", ())
14911491

1492+
WARNING(originally_defined_in_swift_version, none,
1493+
"Swift language version checks has no effect "
1494+
"in @_originallyDefinedIn", ())
1495+
1496+
WARNING(originally_defined_in_package_description, none,
1497+
"PackageDescription version checks has no effect "
1498+
"in @_originallyDefinedIn", ())
1499+
14921500
// convention
14931501
ERROR(convention_attribute_expected_lparen,none,
14941502
"expected '(' after 'convention' attribute", ())

lib/Parse/ParseDecl.cpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,7 +2042,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
20422042
llvm::SmallVector<std::pair<PlatformKind, llvm::VersionTuple>, 4>
20432043
PlatformAndVersions;
20442044

2045-
StringRef AttrName = "@_originalDefinedIn";
2045+
StringRef AttrName = "@_originallyDefinedIn";
20462046
bool SuppressLaterDiags = false;
20472047
if (parseList(tok::r_paren, LeftLoc, RightLoc, false,
20482048
diag::originally_defined_in_missing_rparen,
@@ -2084,9 +2084,53 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
20842084
// Parse 'OSX 13.13'.
20852085
case NextSegmentKind::PlatformVersion: {
20862086
if ((Tok.is(tok::identifier) || Tok.is(tok::oper_binary_spaced)) &&
2087-
(peekToken().is(tok::floating_literal) ||
2088-
peekToken().is(tok::integer_literal))) {
2087+
(peekToken().isAny(tok::integer_literal, tok::floating_literal) ||
2088+
peekAvailabilityMacroName())) {
2089+
20892090
PlatformKind Platform;
2091+
2092+
if (peekAvailabilityMacroName()) {
2093+
// Handle availability macros first.
2094+
//
2095+
// The logic to search for macros and platform name could
2096+
// likely be handled by parseAvailabilitySpecList
2097+
// if we don't rely on parseList here.
2098+
SmallVector<AvailabilitySpec *, 4> Specs;
2099+
ParserStatus MacroStatus = parseAvailabilityMacro(Specs);
2100+
if (MacroStatus.isError())
2101+
return MacroStatus;
2102+
2103+
for (auto *Spec : Specs) {
2104+
if (auto *PlatformVersionSpec =
2105+
dyn_cast<PlatformVersionConstraintAvailabilitySpec>(Spec)) {
2106+
auto Platform = PlatformVersionSpec->getPlatform();
2107+
auto Version = PlatformVersionSpec->getVersion();
2108+
if (Version.getSubminor().hasValue() ||
2109+
Version.getBuild().hasValue()) {
2110+
diagnose(Tok.getLoc(), diag::originally_defined_in_major_minor_only);
2111+
}
2112+
PlatformAndVersions.emplace_back(Platform, Version);
2113+
2114+
} else if (auto *PlatformAgnostic =
2115+
dyn_cast<PlatformAgnosticVersionConstraintAvailabilitySpec>(Spec)) {
2116+
diagnose(PlatformAgnostic->getPlatformAgnosticNameLoc(),
2117+
PlatformAgnostic->isLanguageVersionSpecific() ?
2118+
diag::originally_defined_in_swift_version :
2119+
diag::originally_defined_in_package_description);
2120+
2121+
} else if (auto *OtherPlatform =
2122+
dyn_cast<OtherPlatformAvailabilitySpec>(Spec)) {
2123+
diagnose(OtherPlatform->getStarLoc(),
2124+
diag::originally_defined_in_missing_platform_name);
2125+
2126+
} else {
2127+
llvm_unreachable("Unexpected AvailabilitySpec kind.");
2128+
}
2129+
}
2130+
2131+
return makeParserSuccess();
2132+
}
2133+
20902134
// Parse platform name.
20912135
auto Plat = platformFromString(Tok.getText());
20922136
if (!Plat.hasValue()) {

test/ModuleInterface/originally-defined-attr.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// RUN: %empty-directory(%t)
22

33
// Ensure the attribute is printed in swiftinterface files
4-
// RUN: %target-swift-frontend-typecheck -emit-module-interface-path %t/Foo.swiftinterface %s -module-name Foo
4+
// RUN: %target-swift-frontend-typecheck -emit-module-interface-path %t/Foo.swiftinterface %s -module-name Foo \
5+
// RUN: -define-availability "_iOS8Aligned:macOS 10.10, iOS 8.0" \
6+
// RUN: -define-availability "_iOS9:iOS 9.0" \
7+
// RUN: -define-availability "_macOS10_11:macOS 10.11" \
8+
// RUN: -define-availability "_myProject 1.0:macOS 10.11"
59
// RUN: %FileCheck %s < %t/Foo.swiftinterface
610

711
// Ensure the attribute is in .swiftmodule files
@@ -21,3 +25,20 @@ public protocol SimpleProto { }
2125
@_originallyDefinedIn(module: "original", tvOS 1.0)
2226
@_originallyDefinedIn(module: "another_original", OSX 2.0, iOS 3.0, watchOS 4.0)
2327
public struct SimpleStruct {}
28+
29+
// CHECK: @_originallyDefinedIn(module: "other0", macOS 10.10)
30+
// CHECK: @_originallyDefinedIn(module: "other0", iOS 8.0)
31+
@available(tvOS 0.7, OSX 1.1, iOS 2.1, watchOS 3.2, *)
32+
@_originallyDefinedIn(module: "other0", _iOS8Aligned)
33+
public struct SimpleThingInAlphabeticalOrderForMacros0 {}
34+
35+
// CHECK: @_originallyDefinedIn(module: "other1", iOS 9.0)
36+
// CHECK: @_originallyDefinedIn(module: "other1", macOS 10.11)
37+
@available(tvOS 0.7, OSX 1.1, iOS 2.1, watchOS 3.2, *)
38+
@_originallyDefinedIn(module: "other1", _iOS9, _macOS10_11)
39+
public struct SimpleThingInAlphabeticalOrderForMacros1 {}
40+
41+
// CHECK: @_originallyDefinedIn(module: "other2", macOS 10.11)
42+
@available(tvOS 0.7, OSX 1.1, iOS 2.1, watchOS 3.2, *)
43+
@_originallyDefinedIn(module: "other2", _myProject 1.0)
44+
public struct SimpleThingInAlphabeticalOrderForMacros2 {}

test/Sema/diag_originally_definedin.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift \
2+
// RUN: -define-availability "_myProject 1.0:macOS 10.10"
23
// REQUIRES: OS=macosx
34

45
@_originallyDefinedIn(module: "original", OSX 10.13) // expected-error {{need @available attribute for @_originallyDefinedIn}}
@@ -10,3 +11,13 @@ public class C {
1011
@_originallyDefinedIn(module: "original", OSX 10.13) // expected-error {{@_originallyDefinedIn is only applicable to top-level decl}}
1112
public func foo() {}
1213
}
14+
15+
@available(macOS 10.9, *)
16+
@_originallyDefinedIn(module: "original", _myProject 2.0) // expected-error {{expected at least one platform version in @_originallyDefinedIn}}
17+
// expected-error @-1 {{reference to undefined version '2.0' for availability macro '_myProject'}}
18+
public func macroVersionned() {}
19+
20+
// Fallback to the default diagnostic when the macro is unknown.
21+
@available(macOS 10.9, *)
22+
@_originallyDefinedIn(module: "original", _unknownMacro) // expected-error {{expected at least one platform version in @_originallyDefinedIn}}
23+
public func macroUnknown() {}

test/attr/Inputs/SymbolMove/HighlevelOriginal.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ open class Vehicle {
4747
public init() {}
4848
public var currentSpeed = -40.0
4949
}
50+
51+
public func funcMacro() { print("Macro from HighLevel") }

test/attr/Inputs/SymbolMove/LowLevel.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,8 @@ open class Vehicle {
5151
public init() {}
5252
public var currentSpeed = 40.0
5353
}
54+
55+
// =================== Move from macro ======================= //
56+
@available(OSX 10.7, iOS 7.0, *)
57+
@_originallyDefinedIn(module: "HighLevel", _iOS13Aligned)
58+
public func funcMacro () { print("Macro from LowLevel") }

test/attr/attr_originally_definedin_backward_compatibility.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
// --- Build low level framework.
3131
// RUN: mkdir -p %t/SDK/Frameworks/LowLevel.framework/Modules/LowLevel.swiftmodule
3232
// RUN: %target-build-swift-dylib(%t/SDK/Frameworks/LowLevel.framework/LowLevel) -module-name LowLevel -emit-module \
33-
// RUN: -emit-module-path %t/SDK/Frameworks/LowLevel.framework/Modules/LowLevel.swiftmodule/%module-target-triple.swiftmodule \
34-
// RUN: %S/Inputs/SymbolMove/LowLevel.swift -Xlinker -install_name -Xlinker @rpath/LowLevel.framework/LowLevel -enable-library-evolution
33+
// RUN: -emit-module-path %t/SDK/Frameworks/LowLevel.framework/Modules/LowLevel.swiftmodule/%module-target-triple.swiftmodule \
34+
// RUN: %S/Inputs/SymbolMove/LowLevel.swift -Xlinker -install_name -Xlinker @rpath/LowLevel.framework/LowLevel -enable-library-evolution \
35+
// RUN: -Xfrontend -define-availability -Xfrontend "_iOS13Aligned:macOS 10.10, iOS 8.0"
3536

3637
// --- Build high level framework.
3738
// RUN: mkdir -p %t/SDK/Frameworks/HighLevel.framework/Modules/HighLevel.swiftmodule
@@ -81,3 +82,7 @@ print("\(bicycle.currentSpeed)")
8182

8283
// BEFORE_MOVE: 15.0
8384
// AFTER_MOVE: 15.0
85+
86+
funcMacro()
87+
// BEFORE_MOVE: Macro from HighLevel
88+
// AFTER_MOVE: Macro from LowLevel

0 commit comments

Comments
 (0)