@@ -1771,15 +1771,31 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
1771
1771
Loc, Context.AllocateCopy (Exprs)));
1772
1772
}
1773
1773
1774
- void Parser::diagnoseEscapedArgumentLabel (const Token &tok) {
1775
- assert (tok.isEscapedIdentifier () && " Only for escaped identifiers" );
1776
- if (!canBeArgumentLabel (tok.getText ())) return ;
1777
-
1778
- SourceLoc start = tok.getLoc ();
1779
- SourceLoc end = start.getAdvancedLoc (tok.getLength ());
1780
- diagnose (tok, diag::escaped_parameter_name, tok.getText ())
1781
- .fixItRemoveChars (start, start.getAdvancedLoc (1 ))
1782
- .fixItRemoveChars (end.getAdvancedLoc (-1 ), end);
1774
+ void Parser::parseOptionalArgumentLabel (Identifier &name, SourceLoc &loc) {
1775
+ // Check to see if there is an argument label.
1776
+ if (Tok.canBeArgumentLabel () && peekToken ().is (tok::colon)) {
1777
+ auto text = Tok.getText ();
1778
+
1779
+ // If this was an escaped identifier that need not have been escaped, say
1780
+ // so. Only _ needs escaping, because we take foo(_: 3) to be equivalent
1781
+ // to foo(3), to be more uniform with _ in function declaration as well as
1782
+ // the syntax for referring to the function pointer (foo(_:)),
1783
+ auto escaped = Tok.isEscapedIdentifier ();
1784
+ auto underscore = Tok.is (tok::kw__) || (escaped && text == " _" );
1785
+ if (escaped && !underscore && canBeArgumentLabel (text)) {
1786
+ SourceLoc start = Tok.getLoc ();
1787
+ SourceLoc end = start.getAdvancedLoc (Tok.getLength ());
1788
+ diagnose (Tok, diag::escaped_parameter_name, text)
1789
+ .fixItRemoveChars (start, start.getAdvancedLoc (1 ))
1790
+ .fixItRemoveChars (end.getAdvancedLoc (-1 ), end);
1791
+ }
1792
+
1793
+ auto unescapedUnderscore = underscore && !escaped;
1794
+ if (!unescapedUnderscore)
1795
+ name = Context.getIdentifier (text);
1796
+ loc = consumeToken ();
1797
+ consumeToken (tok::colon);
1798
+ }
1783
1799
}
1784
1800
1785
1801
DeclName Parser::parseUnqualifiedDeclName (bool afterDot,
@@ -1834,20 +1850,12 @@ DeclName Parser::parseUnqualifiedDeclName(bool afterDot,
1834
1850
argumentLabelLocs.push_back (consumeToken (tok::colon));
1835
1851
}
1836
1852
1837
- // If we see a potential argument label followed by a ':', consume
1838
- // it.
1839
- if (Tok.canBeArgumentLabel () && peekToken ().is (tok::colon)) {
1840
- // If this was an escaped identifier that need not have been escaped,
1841
- // say so.
1842
- if (Tok.isEscapedIdentifier ())
1843
- diagnoseEscapedArgumentLabel (Tok);
1844
-
1845
- if (Tok.is (tok::kw__))
1846
- argumentLabels.push_back (Identifier ());
1847
- else
1848
- argumentLabels.push_back (Context.getIdentifier (Tok.getText ()));
1849
- argumentLabelLocs.push_back (consumeToken ());
1850
- (void )consumeToken (tok::colon);
1853
+ Identifier argName;
1854
+ SourceLoc argLoc;
1855
+ parseOptionalArgumentLabel (argName, argLoc);
1856
+ if (argLoc.isValid ()) {
1857
+ argumentLabels.push_back (argName);
1858
+ argumentLabelLocs.push_back (argLoc);
1851
1859
continue ;
1852
1860
}
1853
1861
@@ -2569,19 +2577,7 @@ ParserStatus Parser::parseExprList(tok leftTok, tok rightTok,
2569
2577
[&] () -> ParserStatus {
2570
2578
Identifier FieldName;
2571
2579
SourceLoc FieldNameLoc;
2572
-
2573
- // Check to see if there is an argument label.
2574
- if (Tok.canBeArgumentLabel () && peekToken ().is (tok::colon)) {
2575
- // If this was an escaped identifier that need not have been escaped,
2576
- // say so.
2577
- if (Tok.isEscapedIdentifier ())
2578
- diagnoseEscapedArgumentLabel (Tok);
2579
-
2580
- if (!Tok.is (tok::kw__))
2581
- FieldName = Context.getIdentifier (Tok.getText ());
2582
- FieldNameLoc = consumeToken ();
2583
- consumeToken (tok::colon);
2584
- }
2580
+ parseOptionalArgumentLabel (FieldName, FieldNameLoc);
2585
2581
2586
2582
// See if we have an operator decl ref '(<op>)'. The operator token in
2587
2583
// this case lexes as a binary operator because it neither leads nor
0 commit comments