@@ -5466,17 +5466,8 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) {
5466
5466
5467
5467
Identifier Name = Context.getIdentifier (Tok.getText ());
5468
5468
SourceLoc NameLoc = consumeToken ();
5469
-
5470
- ParserResult<OperatorDecl> Result;
5471
- if (Attributes.hasAttribute <PrefixAttr>())
5472
- Result = parseDeclPrefixOperator (OperatorLoc, Name, NameLoc, Attributes);
5473
- else if (Attributes.hasAttribute <PostfixAttr>())
5474
- Result = parseDeclPostfixOperator (OperatorLoc, Name, NameLoc, Attributes);
5475
- else {
5476
- if (!Attributes.hasAttribute <InfixAttr>())
5477
- diagnose (OperatorLoc, diag::operator_decl_no_fixity);
5478
- Result = parseDeclInfixOperator (OperatorLoc, Name, NameLoc, Attributes);
5479
- }
5469
+
5470
+ auto Result = parseDeclOperatorImpl (OperatorLoc, Name, NameLoc, Attributes);
5480
5471
5481
5472
if (!DCC.movedToTopLevel () && !AllowTopLevel) {
5482
5473
diagnose (OperatorLoc, diag::operator_decl_inner_scope);
@@ -5487,89 +5478,68 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) {
5487
5478
}
5488
5479
5489
5480
ParserResult<OperatorDecl>
5490
- Parser::parseDeclPrefixOperator (SourceLoc OperatorLoc, Identifier Name,
5481
+ Parser::parseDeclOperatorImpl (SourceLoc OperatorLoc, Identifier Name,
5491
5482
SourceLoc NameLoc, DeclAttributes &Attributes) {
5492
- SourceLoc lBraceLoc;
5493
- if (consumeIf (tok::l_brace, lBraceLoc)) {
5494
- auto Diag = diagnose (lBraceLoc, diag::deprecated_operator_body);
5495
- if (Tok.is (tok::r_brace)) {
5496
- SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken (SourceMgr,
5497
- NameLoc);
5498
- SourceLoc rBraceEnd = Lexer::getLocForEndOfToken (SourceMgr, Tok.getLoc ());
5499
- Diag.fixItRemoveChars (lastGoodLocEnd, rBraceEnd);
5500
- }
5501
-
5502
- skipUntilDeclRBrace ();
5503
- (void ) consumeIf (tok::r_brace);
5504
- }
5483
+ bool isPrefix = Attributes.hasAttribute <PrefixAttr>();
5484
+ bool isInfix = Attributes.hasAttribute <InfixAttr>();
5485
+ bool isPostfix = Attributes.hasAttribute <PostfixAttr>();
5505
5486
5506
- auto *Res = new (Context) PrefixOperatorDecl (CurDeclContext, OperatorLoc,
5507
- Name, NameLoc);
5508
- Res->getAttrs () = Attributes;
5509
- return makeParserResult (Res);
5510
- }
5511
-
5512
- ParserResult<OperatorDecl>
5513
- Parser::parseDeclPostfixOperator (SourceLoc OperatorLoc,
5514
- Identifier Name, SourceLoc NameLoc,
5515
- DeclAttributes &Attributes) {
5516
- SourceLoc lBraceLoc;
5517
- if (consumeIf (tok::l_brace, lBraceLoc)) {
5518
- auto Diag = diagnose (lBraceLoc, diag::deprecated_operator_body);
5519
- if (Tok.is (tok::r_brace)) {
5520
- SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken (SourceMgr,
5521
- NameLoc);
5522
- SourceLoc rBraceEnd = Lexer::getLocForEndOfToken (SourceMgr, Tok.getLoc ());
5523
- Diag.fixItRemoveChars (lastGoodLocEnd, rBraceEnd);
5524
- }
5525
-
5526
- skipUntilDeclRBrace ();
5527
- (void ) consumeIf (tok::r_brace);
5528
- }
5529
-
5530
- auto Res = new (Context) PostfixOperatorDecl (CurDeclContext, OperatorLoc,
5531
- Name, NameLoc);
5532
- Res->getAttrs () = Attributes;
5533
- return makeParserResult (Res);
5534
- }
5535
-
5536
- ParserResult<OperatorDecl>
5537
- Parser::parseDeclInfixOperator (SourceLoc operatorLoc, Identifier name,
5538
- SourceLoc nameLoc, DeclAttributes &attributes) {
5487
+ // Parse (or diagnose) a specified precedence group.
5539
5488
SourceLoc colonLoc;
5540
5489
Identifier precedenceGroupName;
5541
5490
SourceLoc precedenceGroupNameLoc;
5542
5491
if (consumeIf (tok::colon, colonLoc)) {
5543
5492
if (Tok.is (tok::identifier)) {
5544
5493
precedenceGroupName = Context.getIdentifier (Tok.getText ());
5545
5494
precedenceGroupNameLoc = consumeToken (tok::identifier);
5495
+
5496
+ if (isPrefix || isPostfix)
5497
+ diagnose (colonLoc, diag::precedencegroup_not_infix)
5498
+ .fixItRemove ({colonLoc, precedenceGroupNameLoc});
5546
5499
}
5547
5500
}
5548
-
5501
+
5502
+ // Diagnose deprecated operator body syntax `operator + { ... }`.
5549
5503
SourceLoc lBraceLoc;
5550
5504
if (consumeIf (tok::l_brace, lBraceLoc)) {
5551
- if (Tok.is (tok::r_brace)) {
5552
- SourceLoc lastGoodLoc = precedenceGroupNameLoc;
5553
- if (lastGoodLoc.isInvalid ())
5554
- lastGoodLoc = nameLoc;
5555
- SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken (SourceMgr,
5556
- lastGoodLoc);
5557
- SourceLoc rBraceEnd = Lexer::getLocForEndOfToken (SourceMgr, Tok.getLoc ());
5558
- diagnose (lBraceLoc, diag::deprecated_operator_body)
5559
- .fixItRemoveChars (lastGoodLocEnd, rBraceEnd);
5560
- } else {
5505
+ if (isInfix && !Tok.is (tok::r_brace)) {
5561
5506
diagnose (lBraceLoc, diag::deprecated_operator_body_use_group);
5507
+ } else {
5508
+ auto Diag = diagnose (lBraceLoc, diag::deprecated_operator_body);
5509
+ if (Tok.is (tok::r_brace)) {
5510
+ SourceLoc lastGoodLoc = precedenceGroupNameLoc;
5511
+ if (lastGoodLoc.isInvalid ())
5512
+ lastGoodLoc = NameLoc;
5513
+ SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken (SourceMgr,
5514
+ lastGoodLoc);
5515
+ SourceLoc rBraceEnd = Lexer::getLocForEndOfToken (SourceMgr, Tok.getLoc ());
5516
+ Diag.fixItRemoveChars (lastGoodLocEnd, rBraceEnd);
5517
+ }
5562
5518
}
5563
5519
5564
5520
skipUntilDeclRBrace ();
5565
5521
(void ) consumeIf (tok::r_brace);
5566
5522
}
5567
-
5568
- auto res = new (Context) InfixOperatorDecl (CurDeclContext, operatorLoc,
5569
- name, nameLoc, colonLoc,
5570
- precedenceGroupName,
5571
- precedenceGroupNameLoc);
5572
- res->getAttrs () = attributes;
5523
+
5524
+
5525
+ OperatorDecl *res;
5526
+ if (Attributes.hasAttribute <PrefixAttr>())
5527
+ res = new (Context) PrefixOperatorDecl (CurDeclContext, OperatorLoc,
5528
+ Name, NameLoc);
5529
+ else if (Attributes.hasAttribute <PostfixAttr>())
5530
+ res = new (Context) PostfixOperatorDecl (CurDeclContext, OperatorLoc,
5531
+ Name, NameLoc);
5532
+ else {
5533
+ if (!Attributes.hasAttribute <InfixAttr>())
5534
+ diagnose (OperatorLoc, diag::operator_decl_no_fixity);
5535
+
5536
+ res = new (Context) InfixOperatorDecl (CurDeclContext, OperatorLoc,
5537
+ Name, NameLoc, colonLoc,
5538
+ precedenceGroupName,
5539
+ precedenceGroupNameLoc);
5540
+ }
5541
+
5542
+ res->getAttrs () = Attributes;
5573
5543
return makeParserResult (res);
5574
5544
}
5575
5545
0 commit comments