@@ -1570,6 +1570,44 @@ void Parser::parseAllAvailabilityMacroArguments() {
1570
1570
AvailabilityMacrosComputed = true ;
1571
1571
}
1572
1572
1573
+ static HasAsyncAlternativeAttr *parseAsyncAlternativeAttribute (
1574
+ Parser &P, StringRef AttrName, SourceLoc AtLoc, DeclAttrKind DK) {
1575
+ SourceLoc Loc = P.PreviousLoc ;
1576
+
1577
+ // Unnamed @hasAsyncAlternative attribute
1578
+ if (P.Tok .isNot (tok::l_paren))
1579
+ return new (P.Context ) HasAsyncAlternativeAttr (AtLoc, Loc);
1580
+
1581
+ P.consumeToken (tok::l_paren);
1582
+
1583
+ if (!P.Tok .is (tok::string_literal)) {
1584
+ P.diagnose (Loc, diag::attr_expected_string_literal, AttrName);
1585
+ return nullptr ;
1586
+ }
1587
+
1588
+ auto Value = P.getStringLiteralIfNotInterpolated (
1589
+ Loc, (" argument of '" + AttrName + " '" ).str ());
1590
+ P.consumeToken (tok::string_literal);
1591
+ if (!Value)
1592
+ return nullptr ;
1593
+
1594
+ ParsedDeclName parsedName = parseDeclName (Value.getValue ());
1595
+ if (!parsedName || !parsedName.ContextName .empty ()) {
1596
+ P.diagnose (AtLoc, diag::has_async_alternative_invalid_name, AttrName);;
1597
+ return nullptr ;
1598
+ }
1599
+
1600
+ SourceRange AttrRange = SourceRange (Loc, P.Tok .getRange ().getStart ());
1601
+ if (!P.consumeIf (tok::r_paren)) {
1602
+ P.diagnose (Loc, diag::attr_expected_rparen, AttrName,
1603
+ DeclAttribute::isDeclModifier (DK));
1604
+ return nullptr ;
1605
+ }
1606
+
1607
+ return new (P.Context ) HasAsyncAlternativeAttr (
1608
+ parsedName.formDeclNameRef (P.Context ), AtLoc, AttrRange);
1609
+ }
1610
+
1573
1611
bool Parser::parseNewDeclAttribute (DeclAttributes &Attributes, SourceLoc AtLoc,
1574
1612
DeclAttrKind DK, bool isFromClangAttribute) {
1575
1613
// Ok, it is a valid attribute, eat it, and then process it.
@@ -2648,6 +2686,22 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
2648
2686
name, AtLoc, range, /* implicit*/ false ));
2649
2687
break ;
2650
2688
}
2689
+ case DAK_HasAsyncAlternative: {
2690
+ auto *attr = parseAsyncAlternativeAttribute (*this , AttrName, AtLoc, DK);
2691
+ if (!attr) {
2692
+ skipUntilDeclStmtRBrace (tok::r_paren);
2693
+ consumeIf (tok::r_paren);
2694
+ return false ;
2695
+ }
2696
+
2697
+ if (!DiscardAttribute) {
2698
+ if (Context.LangOpts .EnableExperimentalHasAsyncAlternative )
2699
+ Attributes.add (attr);
2700
+ else
2701
+ diagnose (Loc, diag::requires_has_async_alternative, AttrName);
2702
+ }
2703
+ break ;
2704
+ }
2651
2705
}
2652
2706
2653
2707
if (DuplicateAttribute) {
0 commit comments