@@ -1738,6 +1738,64 @@ void Parser::parseAllAvailabilityMacroArguments() {
1738
1738
AvailabilityMacrosComputed = true ;
1739
1739
}
1740
1740
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
+
1741
1799
// / Processes a parsed option name by attempting to match it to a list of
1742
1800
// / alternative name/value pairs provided by a chain of \c when() calls, ending
1743
1801
// / in either \c whenOmitted() if omitting the option is allowed, or
@@ -2862,65 +2920,27 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
2862
2920
DeclAttribute::isDeclModifier (DK));
2863
2921
return false ;
2864
2922
}
2865
- SourceLoc RightLoc;
2923
+
2866
2924
bool SuppressLaterDiags = false ;
2867
- llvm::SmallVector<std::pair<PlatformKind, llvm::VersionTuple>, 4 >
2868
- PlatformAndVersions;
2869
-
2925
+ SourceLoc RightLoc;
2926
+ llvm::SmallVector<PlatformAndVersion, 4 > PlatformAndVersions;
2870
2927
StringRef AttrName = " @_backDeploy" ;
2871
- if (parseList (tok::r_paren, LeftLoc, RightLoc, false ,
2872
- diag::attr_back_deploy_missing_rparen,
2873
- SyntaxKind::Unknown, [&]() -> ParserStatus {
2874
- // FIXME(backDeploy): Parse availability macros (e.g. SwiftStdlib: 5.1)
2875
-
2876
- // Parse a platform and version tuple (e.g. 'macOS 13.13').
2877
- if ((Tok.is (tok::identifier) || Tok.is (tok::oper_binary_spaced)) &&
2878
- (peekToken ().is (tok::floating_literal) ||
2879
- peekToken ().is (tok::integer_literal))) {
2880
- PlatformKind Platform;
2881
- // Parse platform name.
2882
- auto Plat = platformFromString (Tok.getText ());
2883
- if (!Plat.hasValue ()) {
2884
- diagnose (Tok.getLoc (), diag::attr_availability_unknown_platform,
2885
- Tok.getText (), AttrName);
2886
- SuppressLaterDiags = true ;
2887
- return makeParserError ();
2888
- } else {
2889
- consumeToken ();
2890
- Platform = *Plat;
2891
- }
2892
- // Parse version number
2893
- llvm::VersionTuple VerTuple;
2894
- SourceRange VersionRange;
2895
- if (parseVersionTuple (VerTuple, VersionRange,
2896
- Diagnostic (diag::attr_availability_expected_version, AttrName))) {
2897
- SuppressLaterDiags = true ;
2898
- return makeParserError ();
2899
- } else {
2900
- if (VerTuple.getSubminor ().hasValue () ||
2901
- VerTuple.getBuild ().hasValue ()) {
2902
- diagnose (Tok.getLoc (),
2903
- diag::attr_availability_platform_version_major_minor_only,
2904
- AttrName);
2905
- }
2906
- // * as platform name isn't supported.
2907
- if (Platform == PlatformKind::none) {
2908
- diagnose (AtLoc, diag::attr_availability_wildcard_ignored, AttrName);
2909
- } else {
2910
- PlatformAndVersions.emplace_back (Platform, VerTuple);
2911
- }
2912
- return makeParserSuccess ();
2913
- }
2914
- }
2915
- diagnose (AtLoc, diag::attr_availability_need_platform_version, AttrName);
2916
- SuppressLaterDiags = true ;
2917
- return makeParserError ();
2918
- }).isErrorOrHasCompletion () || SuppressLaterDiags) {
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) {
2919
2939
return false ;
2920
2940
}
2921
2941
2922
2942
if (PlatformAndVersions.empty ()) {
2923
- diagnose (AtLoc , diag::attr_availability_need_platform_version, AttrName);
2943
+ diagnose (Loc , diag::attr_availability_need_platform_version, AttrName);
2924
2944
return false ;
2925
2945
}
2926
2946
0 commit comments