Skip to content

Commit ed76647

Browse files
committed
Use parseDeclNameRef in a few more places
1 parent 7a500a6 commit ed76647

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,5 +2199,9 @@ ERROR(using_decl_invalid_specifier,PointsToFirstBadToken,
21992199
ERROR(experimental_using_decl_disabled,PointsToFirstBadToken,
22002200
"'using' is an experimental feature that is currently disabled", ())
22012201

2202+
ERROR(impossible_parse,none,
2203+
"parser entered impossible state; please file a bug report with this "
2204+
"source file", ())
2205+
22022206
#define UNDEFINE_DIAGNOSTIC_MACROS
22032207
#include "DefineDiagnosticMacros.h"

include/swift/Parse/Parser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,13 +1822,19 @@ class Parser {
18221822
/// cases this doesn't actually make sense but we need to accept them for
18231823
/// backwards compatibility.
18241824
AllowLowercaseAndUppercaseSelf = 1 << 6,
1825+
1826+
/// If passed, `$0` etc. are allowed.
1827+
AllowAnonymousParamNames = 1 << 7,
18251828
};
18261829
using DeclNameOptions = OptionSet<DeclNameFlag>;
18271830

18281831
friend DeclNameOptions operator|(DeclNameFlag flag1, DeclNameFlag flag2) {
18291832
return DeclNameOptions(flag1) | flag2;
18301833
}
18311834

1835+
/// Parse a declaration name that results in a `DeclNameRef` in the syntax
1836+
/// tree.
1837+
///
18321838
/// Without \c DeclNameFlag::AllowCompoundNames, parse an
18331839
/// unqualified-decl-base-name.
18341840
///

lib/Parse/ParseDecl.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10287,8 +10287,9 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1028710287
// designated protocol. These both look like identifiers, so we
1028810288
// parse them both as identifiers here and sort it out in type
1028910289
// checking.
10290-
SourceLoc colonLoc, groupLoc;
10291-
Identifier groupName;
10290+
SourceLoc colonLoc;
10291+
DeclNameLoc groupLoc;
10292+
DeclNameRef groupName;
1029210293
if (Tok.is(tok::colon)) {
1029310294
colonLoc = consumeToken();
1029410295
if (Tok.is(tok::code_complete)) {
@@ -10301,9 +10302,9 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1030110302
return makeParserCodeCompletionResult<OperatorDecl>();
1030210303
}
1030310304

10304-
(void)parseIdentifier(groupName, groupLoc,
10305-
diag::operator_decl_expected_precedencegroup,
10306-
/*diagnoseDollarPrefix=*/false);
10305+
groupName = parseDeclNameRef(groupLoc,
10306+
diag::operator_decl_expected_precedencegroup,
10307+
{});
1030710308

1030810309
if (Context.TypeCheckerOpts.EnableOperatorDesignatedTypes) {
1030910310
// Designated types have been removed; consume the list (mainly for source
@@ -10318,7 +10319,7 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1031810319
// These have no precedence group, so we already parsed the first entry
1031910320
// in the designated types list. Retroactively include it in the range.
1032010321
typesStartLoc = colonLoc;
10321-
typesEndLoc = groupLoc;
10322+
typesEndLoc = groupLoc.getEndLoc();
1032210323
}
1032310324

1032410325
while (Tok.isNot(tok::eof)) {
@@ -10337,7 +10338,7 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1033710338
} else {
1033810339
if (isPrefix || isPostfix) {
1033910340
// If we have nothing after the colon, then just remove the colon.
10340-
auto endLoc = groupLoc.isValid() ? groupLoc : colonLoc;
10341+
auto endLoc = groupLoc.isValid() ? groupLoc.getEndLoc() : colonLoc;
1034110342
diagnose(colonLoc, diag::precedencegroup_not_infix)
1034210343
.fixItRemove({colonLoc, endLoc});
1034310344
}
@@ -10348,14 +10349,14 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1034810349
}
1034910350

1035010351
// Diagnose deprecated operator body syntax `operator + { ... }`.
10352+
SourceLoc lastGoodLoc = PreviousLoc;
1035110353
SourceLoc lBraceLoc;
1035210354
if (consumeIf(tok::l_brace, lBraceLoc)) {
1035310355
if (isInfix && !Tok.is(tok::r_brace)) {
1035410356
diagnose(lBraceLoc, diag::deprecated_operator_body_use_group);
1035510357
} else {
1035610358
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
1035710359
if (Tok.is(tok::r_brace)) {
10358-
SourceLoc lastGoodLoc = groupLoc.isValid() ? groupLoc : NameLoc;
1035910360
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
1036010361
lastGoodLoc);
1036110362
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
@@ -10377,7 +10378,8 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
1037710378
else
1037810379
res = new (Context)
1037910380
InfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc, colonLoc,
10380-
groupName, groupLoc);
10381+
groupName.getBaseIdentifier(),
10382+
groupLoc.getBaseNameLoc());
1038110383

1038210384
diagnoseOperatorFixityAttributes(*this, Attributes, res);
1038310385

@@ -10596,14 +10598,16 @@ Parser::parseDeclPrecedenceGroup(ParseDeclOptions flags,
1059610598
return abortBody(/*hasCodeCompletion*/true);
1059710599
}
1059810600

10599-
if (Tok.isNot(tok::identifier)) {
10600-
diagnose(Tok, diag::expected_precedencegroup_relation, attrName);
10601+
DeclNameLoc nameLoc;
10602+
auto name = parseDeclNameRef(nameLoc,
10603+
{ diag::expected_precedencegroup_relation,
10604+
attrName },
10605+
{});
10606+
if (!name) {
1060110607
return abortBody();
1060210608
}
10603-
Identifier name;
10604-
SourceLoc nameLoc = consumeIdentifier(name,
10605-
/*diagnoseDollarPrefix=*/false);
10606-
relations.push_back({nameLoc, name, nullptr});
10609+
relations.push_back({nameLoc.getBaseNameLoc(), name.getBaseIdentifier(),
10610+
nullptr});
1060710611

1060810612
if (skipUnspacedCodeCompleteToken())
1060910613
return abortBody(/*hasCodeCompletion*/true);

lib/Parse/ParseExpr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,10 @@ DeclNameRef Parser::parseDeclNameRef(DeclNameLoc &loc,
22632263
Identifier baseNameId;
22642264
baseNameLoc = consumeIdentifier(baseNameId, /*diagnoseDollarPrefix=*/false);
22652265
baseName = baseNameId;
2266+
} else if (flags.contains(DeclNameFlag::AllowAnonymousParamNames)
2267+
&& Tok.is(tok::dollarident)) {
2268+
baseName = Context.getIdentifier(Tok.getText());
2269+
baseNameLoc = consumeToken(tok::dollarident);
22662270
} else if (flags.contains(DeclNameFlag::AllowOperators) &&
22672271
Tok.isAnyOperator()) {
22682272
baseName = Context.getIdentifier(Tok.getText());
@@ -3047,8 +3051,13 @@ ParserResult<Expr> Parser::parseExprClosure() {
30473051
/// expr-anon-closure-argument:
30483052
/// dollarident
30493053
Expr *Parser::parseExprAnonClosureArg() {
3050-
StringRef Name = Tok.getText();
3051-
SourceLoc Loc = consumeToken(tok::dollarident);
3054+
DeclNameLoc nameLoc;
3055+
DeclNameRef nameRef =
3056+
parseDeclNameRef(nameLoc, diag::impossible_parse,
3057+
DeclNameFlag::AllowAnonymousParamNames);
3058+
3059+
StringRef Name = nameRef.getBaseIdentifier().str();
3060+
SourceLoc Loc = nameLoc.getBaseNameLoc();
30523061
assert(Name[0] == '$' && "Not a dollarident");
30533062

30543063
// We know from the lexer that this is all-numeric.

test/Parse/operator_decl.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ precedencegroup D {
8383
precedencegroup E {
8484
higherThan:
8585
} // expected-error {{expected name of related precedence group after 'higherThan'}}
86+
precedencegroup EE {
87+
higherThan: E,
88+
} // expected-error {{expected name of related precedence group after 'higherThan'}}
8689

8790
precedencegroup F {
8891
higherThan: A, B, C

0 commit comments

Comments
 (0)