@@ -1738,6 +1738,64 @@ void Parser::parseAllAvailabilityMacroArguments() {
17381738 AvailabilityMacrosComputed = true ;
17391739}
17401740
1741+ ParserStatus Parser::parsePlatformVersionInList (StringRef AttrName,
1742+ llvm::SmallVector<PlatformAndVersion, 4 > &PlatformAndVersions) {
1743+ // FIXME(backDeploy): Parse availability macros (e.g. SwiftStdlib: 5.1)
1744+ SyntaxParsingContext argumentContext (SyntaxContext,
1745+ SyntaxKind::AvailabilityVersionRestriction);
1746+
1747+ // Expect a possible platform name (e.g. 'macOS' or '*').
1748+ if (!Tok.isAny (tok::identifier, tok::oper_binary_spaced)) {
1749+ diagnose (Tok, diag::attr_availability_expected_platform, AttrName);
1750+ return makeParserError ();
1751+ }
1752+
1753+ // Parse the platform name.
1754+ auto MaybePlatform = platformFromString (Tok.getText ());
1755+ SourceLoc PlatformLoc = Tok.getLoc ();
1756+ if (!MaybePlatform.hasValue ()) {
1757+ diagnose (PlatformLoc, diag::attr_availability_unknown_platform,
1758+ Tok.getText (), AttrName);
1759+ return makeParserError ();
1760+ }
1761+ consumeToken ();
1762+ PlatformKind Platform = *MaybePlatform;
1763+
1764+ // Wildcards ('*') aren't supported in this kind of list. If this list
1765+ // entry is just a wildcard, skip it. Wildcards with a version are
1766+ // diagnosed below.
1767+ if (Platform == PlatformKind::none && Tok.isAny (tok::comma, tok::r_paren)) {
1768+ diagnose (PlatformLoc, diag::attr_availability_wildcard_ignored,
1769+ AttrName);
1770+ return makeParserSuccess ();
1771+ }
1772+
1773+ // Parse version number.
1774+ llvm::VersionTuple VerTuple;
1775+ SourceRange VersionRange;
1776+ if (parseVersionTuple (VerTuple, VersionRange,
1777+ Diagnostic (diag::attr_availability_expected_version, AttrName))) {
1778+ return makeParserError ();
1779+ }
1780+
1781+ // Diagnose specification of patch versions (e.g. '13.0.1').
1782+ if (VerTuple.getSubminor ().hasValue () ||
1783+ VerTuple.getBuild ().hasValue ()) {
1784+ diagnose (VersionRange.Start ,
1785+ diag::attr_availability_platform_version_major_minor_only,
1786+ AttrName);
1787+ }
1788+
1789+ // Wildcards ('*') aren't supported in this kind of list.
1790+ if (Platform == PlatformKind::none) {
1791+ diagnose (PlatformLoc, diag::attr_availability_wildcard_ignored,
1792+ AttrName);
1793+ } else {
1794+ PlatformAndVersions.emplace_back (Platform, VerTuple);
1795+ }
1796+ return makeParserSuccess ();
1797+ }
1798+
17411799// / Processes a parsed option name by attempting to match it to a list of
17421800// / alternative name/value pairs provided by a chain of \c when() calls, ending
17431801// / in either \c whenOmitted() if omitting the option is allowed, or
@@ -2855,6 +2913,47 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
28552913 message, AtLoc, SourceRange (Loc, Tok.getLoc ()), false ));
28562914 break ;
28572915 }
2916+ case DAK_BackDeploy: {
2917+ auto LeftLoc = Tok.getLoc ();
2918+ if (!consumeIf (tok::l_paren)) {
2919+ diagnose (Loc, diag::attr_expected_lparen, AttrName,
2920+ DeclAttribute::isDeclModifier (DK));
2921+ return false ;
2922+ }
2923+
2924+ bool SuppressLaterDiags = false ;
2925+ SourceLoc RightLoc;
2926+ llvm::SmallVector<PlatformAndVersion, 4 > PlatformAndVersions;
2927+ StringRef AttrName = " @_backDeploy" ;
2928+ ParserStatus Status = parseList (tok::r_paren, LeftLoc, RightLoc, false ,
2929+ diag::attr_back_deploy_missing_rparen,
2930+ SyntaxKind::Unknown, [&]() -> ParserStatus {
2931+ ParserStatus ListItemStatus =
2932+ parsePlatformVersionInList (AttrName, PlatformAndVersions);
2933+ if (ListItemStatus.isErrorOrHasCompletion ())
2934+ SuppressLaterDiags = true ;
2935+ return ListItemStatus;
2936+ });
2937+
2938+ if (Status.isErrorOrHasCompletion () || SuppressLaterDiags) {
2939+ return false ;
2940+ }
2941+
2942+ if (PlatformAndVersions.empty ()) {
2943+ diagnose (Loc, diag::attr_availability_need_platform_version, AttrName);
2944+ return false ;
2945+ }
2946+
2947+ assert (!PlatformAndVersions.empty ());
2948+ AttrRange = SourceRange (Loc, Tok.getLoc ());
2949+ for (auto &Item: PlatformAndVersions) {
2950+ Attributes.add (new (Context) BackDeployAttr (AtLoc, AttrRange,
2951+ Item.first ,
2952+ Item.second ,
2953+ /* IsImplicit*/ false ));
2954+ }
2955+ break ;
2956+ }
28582957 }
28592958
28602959 if (DuplicateAttribute) {
0 commit comments