Skip to content

Commit 4bebead

Browse files
committed
[Parser] Better error-recovery to preserve operator decl's structures.
1 parent 2e6e7d8 commit 4bebead

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5525,25 +5525,37 @@ Parser::parseDeclInfixOperator(SourceLoc OperatorLoc, Identifier Name,
55255525
SourceLoc AssociativityLoc, AssociativityValueLoc,
55265526
PrecedenceLoc, PrecedenceValueLoc,
55275527
AssignmentLoc;
5528-
5528+
5529+
auto ErrReturnFunc = [&] () {
5530+
skipUntilDeclRBrace();
5531+
assert(Tok.getKind() == tok::r_brace);
5532+
SourceLoc RBraceLoc = Tok.getLoc();
5533+
auto Res = new (Context)
5534+
InfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc, LBraceLoc,
5535+
AssociativityLoc.isInvalid(), AssociativityLoc,
5536+
AssociativityValueLoc, PrecedenceLoc.isInvalid(),
5537+
PrecedenceLoc, PrecedenceValueLoc,
5538+
AssignmentLoc.isInvalid(), AssignmentLoc,
5539+
RBraceLoc,
5540+
InfixData(precedence, associativity, assignment));
5541+
Res->getAttrs() = Attributes;
5542+
return makeParserErrorResult(Res);
5543+
};
55295544
while (!Tok.is(tok::r_brace)) {
55305545
if (!Tok.is(tok::identifier)) {
55315546
diagnose(Tok, diag::expected_operator_attribute);
5532-
skipUntilDeclRBrace();
5533-
return nullptr;
5547+
return ErrReturnFunc();
55345548
}
55355549

55365550
if (Tok.getText().equals("associativity")) {
55375551
if (AssociativityLoc.isValid()) {
55385552
diagnose(Tok, diag::operator_associativity_redeclared);
5539-
skipUntilDeclRBrace();
5540-
return nullptr;
5553+
return ErrReturnFunc();
55415554
}
55425555
AssociativityLoc = consumeToken();
55435556
if (!Tok.is(tok::identifier)) {
55445557
diagnose(Tok, diag::expected_infix_operator_associativity);
5545-
skipUntilDeclRBrace();
5546-
return nullptr;
5558+
return ErrReturnFunc();
55475559
}
55485560
auto parsedAssociativity
55495561
= llvm::StringSwitch<Optional<Associativity>>(Tok.getText())
@@ -5553,8 +5565,7 @@ Parser::parseDeclInfixOperator(SourceLoc OperatorLoc, Identifier Name,
55535565
.Default(None);
55545566
if (!parsedAssociativity) {
55555567
diagnose(Tok, diag::unknown_infix_operator_associativity, Tok.getText());
5556-
skipUntilDeclRBrace();
5557-
return nullptr;
5568+
return ErrReturnFunc();
55585569
}
55595570
associativity = *parsedAssociativity;
55605571

@@ -5565,14 +5576,12 @@ Parser::parseDeclInfixOperator(SourceLoc OperatorLoc, Identifier Name,
55655576
if (Tok.getText().equals("precedence")) {
55665577
if (PrecedenceLoc.isValid()) {
55675578
diagnose(Tok, diag::operator_precedence_redeclared);
5568-
skipUntilDeclRBrace();
5569-
return nullptr;
5579+
return ErrReturnFunc();
55705580
}
55715581
PrecedenceLoc = consumeToken();
55725582
if (!Tok.is(tok::integer_literal)) {
55735583
diagnose(Tok, diag::expected_infix_operator_precedence);
5574-
skipUntilDeclRBrace();
5575-
return nullptr;
5584+
return ErrReturnFunc();
55765585
}
55775586
if (Tok.getText().getAsInteger(0, precedence)) {
55785587
diagnose(Tok, diag::invalid_infix_operator_precedence);
@@ -5586,17 +5595,15 @@ Parser::parseDeclInfixOperator(SourceLoc OperatorLoc, Identifier Name,
55865595
if (Tok.getText().equals("assignment")) {
55875596
if (AssignmentLoc.isValid()) {
55885597
diagnose(Tok, diag::operator_assignment_redeclared);
5589-
skipUntilDeclRBrace();
5590-
return nullptr;
5598+
return ErrReturnFunc();
55915599
}
55925600
AssignmentLoc = consumeToken();
55935601
assignment = true;
55945602
continue;
55955603
}
55965604

55975605
diagnose(Tok, diag::unknown_infix_operator_attribute, Tok.getText());
5598-
skipUntilDeclRBrace();
5599-
return nullptr;
5606+
return ErrReturnFunc();
56005607
}
56015608

56025609
SourceLoc RBraceLoc = Tok.getLoc();

0 commit comments

Comments
 (0)