[Sema] Allow unrecognized platforms in @backDeployed and @_originallyDefinedIn

Don't emit attr_availability_need_platform_version for a @backDeployed or @_originallyDefinedIn that have a single unrecognized platform name.
This commit is contained in:
Ian Anderson
2024-08-23 22:34:53 -07:00
parent 629ba5be46
commit eb11ad99a1
5 changed files with 32 additions and 27 deletions

View File

@@ -2104,12 +2104,15 @@ public:
using PlatformAndVersion = std::pair<PlatformKind, llvm::VersionTuple>;
/// Parse a platform and version tuple (e.g. "macOS 12.0") and append it to the
/// given vector. Wildcards ('*') parse successfully but are ignored. Assumes
/// that the tuples are part of a comma separated list ending with a trailing
/// ')'.
ParserStatus parsePlatformVersionInList(StringRef AttrName,
llvm::SmallVector<PlatformAndVersion, 4> &PlatformAndVersions);
/// Parse a platform and version tuple (e.g. "macOS 12.0") and append it to
/// the given vector. Wildcards ('*') parse successfully but are ignored.
/// Unrecognized platform names also parse successfully but are ignored.
/// Assumes that the tuples are part of a comma separated list ending with a
/// trailing ')'.
ParserStatus parsePlatformVersionInList(
StringRef AttrName,
llvm::SmallVector<PlatformAndVersion, 4> & PlatformAndVersions,
bool &ParsedUnrecognizedPlatformName);
//===--------------------------------------------------------------------===//
// Code completion second pass.

View File

@@ -2189,7 +2189,8 @@ void Parser::parseAllAvailabilityMacroArguments() {
}
ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName,
llvm::SmallVector<PlatformAndVersion, 4> &PlatformAndVersions) {
llvm::SmallVector<PlatformAndVersion, 4> &PlatformAndVersions,
bool &ParsedUnrecognizedPlatformName) {
// Check for availability macros first.
if (peekAvailabilityMacroName()) {
SmallVector<AvailabilitySpec *, 4> Specs;
@@ -2226,6 +2227,7 @@ ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName,
// Parse the platform name.
StringRef platformText = Tok.getText();
auto MaybePlatform = platformFromString(platformText);
ParsedUnrecognizedPlatformName = !MaybePlatform.has_value();
SourceLoc PlatformLoc = Tok.getLoc();
consumeToken();
@@ -2288,6 +2290,7 @@ bool Parser::parseBackDeployedAttribute(DeclAttributes &Attributes,
SourceLoc RightLoc;
ParserStatus Status;
bool SuppressLaterDiags = false;
bool ParsedUnrecognizedPlatformName = false;
llvm::SmallVector<PlatformAndVersion, 4> PlatformAndVersions;
{
@@ -2306,12 +2309,12 @@ bool Parser::parseBackDeployedAttribute(DeclAttributes &Attributes,
if (!Tok.is(tok::r_paren)) {
ParseListItemResult Result;
do {
Result = parseListItem(Status, tok::r_paren, LeftLoc, RightLoc,
/*AllowSepAfterLast=*/false,
[&]() -> ParserStatus {
return parsePlatformVersionInList(
AtAttrName, PlatformAndVersions);
});
Result = parseListItem(
Status, tok::r_paren, LeftLoc, RightLoc,
/*AllowSepAfterLast=*/false, [&]() -> ParserStatus {
return parsePlatformVersionInList(AtAttrName, PlatformAndVersions,
ParsedUnrecognizedPlatformName);
});
} while (Result == ParseListItemResult::Continue);
}
}
@@ -2324,12 +2327,11 @@ bool Parser::parseBackDeployedAttribute(DeclAttributes &Attributes,
return false;
}
if (PlatformAndVersions.empty()) {
if (PlatformAndVersions.empty() && !ParsedUnrecognizedPlatformName) {
diagnose(Loc, diag::attr_availability_need_platform_version, AtAttrName);
return false;
}
assert(!PlatformAndVersions.empty());
auto AttrRange = SourceRange(Loc, RightLoc);
for (auto &Item : PlatformAndVersions) {
Attributes.add(new (Context) BackDeployedAttr(AtLoc, AttrRange, Item.first,
@@ -3445,6 +3447,7 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
StringRef AttrName = "@_originallyDefinedIn";
bool SuppressLaterDiags = false;
bool ParsedUnrecognizedPlatformName = false;
if (parseList(tok::r_paren, LeftLoc, RightLoc, false,
diag::originally_defined_in_missing_rparen,
[&]() -> ParserStatus {
@@ -3484,8 +3487,8 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
}
// Parse 'OSX 13.13'.
case NextSegmentKind::PlatformVersion: {
ParserStatus ListItemStatus =
parsePlatformVersionInList(AttrName, PlatformAndVersions);
ParserStatus ListItemStatus = parsePlatformVersionInList(
AttrName, PlatformAndVersions, ParsedUnrecognizedPlatformName);
if (ListItemStatus.isErrorOrHasCompletion())
SuppressLaterDiags = true;
return ListItemStatus;
@@ -3499,13 +3502,13 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
diagnose(AtLoc, diag::originally_defined_in_need_nonempty_module_name);
return makeParserSuccess();
}
if (PlatformAndVersions.empty()) {
if (PlatformAndVersions.empty() && !ParsedUnrecognizedPlatformName) {
diagnose(AtLoc, diag::attr_availability_need_platform_version, AttrName);
return makeParserSuccess();
}
assert(!OriginalModuleName.empty());
assert(!PlatformAndVersions.empty());
assert(NK == NextSegmentKind::PlatformVersion);
AttrRange = SourceRange(Loc, RightLoc);
for (auto &Item: PlatformAndVersions) {

View File

@@ -34,30 +34,24 @@ public func macroUnknown() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", macos 10.13) // expected-warning {{unknown platform 'macos' for attribute '@_originallyDefinedIn'; did you mean 'macOS'?}} {{43-48=macOS}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func incorrectPlatformCase() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", mscos 10.13) // expected-warning {{unknown platform 'mscos' for attribute '@_originallyDefinedIn'; did you mean 'macOS'?}} {{43-48=macOS}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func incorrectPlatformSimilar1() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", macoss 10.13) // expected-warning {{unknown platform 'macoss' for attribute '@_originallyDefinedIn'; did you mean 'macOS'?}} {{43-49=macOS}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func incorrectPlatformSimilar2() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", mac 10.13) // expected-warning {{unknown platform 'mac' for attribute '@_originallyDefinedIn'; did you mean 'macOS'?}} {{43-46=macOS}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func incorrectPlatformSimilar3() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", notValid 10.13) // expected-warning {{unknown platform 'notValid' for attribute '@_originallyDefinedIn'}} {{none}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func incorrectPlatformNotSimilar() {}
@available(macOS 10.9, *)
@_originallyDefinedIn(module: "original", swift 5.1) // expected-warning {{unknown platform 'swift' for attribute '@_originallyDefinedIn'}}
// expected-error@-1 {{expected at least one platform version in '@_originallyDefinedIn' attribute}}
public func swiftVersionMacro() {}

View File

@@ -5,7 +5,9 @@ public func printMessageMoved() {
}
@available(OSX 10.7, iOS 7.0, *)
@available(unrecognizedOS 1.0, *)
@_originallyDefinedIn(module: "HighLevel", OSX 10.9, iOS 13.0)
@_originallyDefinedIn(module: "HighLevel", unrecognizedOS 2.0)
public struct Entity {
public let value = "LowLevel"
public init() {}

View File

@@ -367,7 +367,11 @@ public func incorrectPlatformCaseFunc() {}
public func incorrectPlatformSimilarFunc() {}
@backDeployed(before: macOS 12.0, unknownOS 1.0) // expected-warning {{unknown platform 'unknownOS' for attribute '@backDeployed'}}
public func unknownOSFunc() {}
public func unknownOSFunc1() {}
@backDeployed(before: macOS 12.0)
@backDeployed(before: unknownOS 1.0) // expected-warning {{unknown platform 'unknownOS' for attribute '@backDeployed'}}
public func unknownOSFunc2() {}
@backDeployed(before: @) // expected-error {{expected platform in '@backDeployed' attribute}}
public func badPlatformFunc1() {}
@@ -414,7 +418,6 @@ public func missingMacroVersion() {}
public func unknownMacroMissingVersion() {}
@backDeployed(before: _unknownMacro 1.0) // expected-warning {{unknown platform '_unknownMacro' for attribute '@backDeployed'}}
// expected-error@-1 {{expected at least one platform version in '@backDeployed' attribute}}
public func unknownMacroVersioned() {}
@backDeployed(before: _unknownMacro 1.0, _myProject 2.0) // expected-warning {{unknown platform '_unknownMacro' for attribute '@backDeployed'}}