Extend the error of invalid token after declarations to include fixits for
!=, %=, ^=, &=, *=, -=, |=, /=, <<=, <=, >=, and >>= to =.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148499 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index fa57dd2..047d6ce 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -154,10 +154,8 @@
def err_expected_method_body : Error<"expected method body">;
def err_invalid_token_after_toplevel_declarator : Error<
"expected ';' after top level declarator">;
-def err_invalid_equalequal_after_declarator : Error<
- "invalid '==' at end of declaration; did you mean '='?">;
-def err_invalid_plusequal_after_declarator : Error<
- "invalid '+=' at end of declaration; did you mean '='?">;
+def err_invalid_token_after_declarator_suggest_equal : Error<
+ "invalid '%0' at end of declaration; did you mean '='?">;
def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_lparen_after_id : Error<"expected '(' after %0">;
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index c36f34a..ea79b98 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -288,12 +288,9 @@
Tok.getKind() == tok::utf32_string_literal;
}
- /// \brief Returns true if the current token is FoundToken. This token
- /// will be assumed a typo. A diagnostic will be emitted with DiagID with a
- /// a fixit to replace the current token with ExpectedToken.
- bool CreateTokenReplacement(tok::TokenKind ExpectedToken,
- tok::TokenKind FoundToken,
- unsigned DiagID);
+ /// \brief Returns true if the current token is '=' or is a type of '='.
+ /// For typos, give a fixit to '='
+ bool isTokenEqualOrEqualTypo();
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
/// This does not work with all kinds of tokens: strings and specific other
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 0de8c53..00a0339 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1270,11 +1270,7 @@
// Parse declarator '=' initializer.
// If a '==' or '+=' is found, suggest a fixit to '='.
- if (Tok.is(tok::equal) ||
- CreateTokenReplacement(tok::equal, tok::equalequal,
- diag::err_invalid_equalequal_after_declarator) ||
- CreateTokenReplacement(tok::equal, tok::plusequal,
- diag::err_invalid_plusequal_after_declarator)) {
+ if (isTokenEqualOrEqualTypo()) {
ConsumeToken();
if (Tok.is(tok::kw_delete)) {
if (D.isFunctionDeclarator())
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 831c446..a115f18 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1260,11 +1260,7 @@
// '=' assignment-expression
// If a '==' or '+=' is found, suggest a fixit to '='.
- if (Tok.is(tok::equal) ||
- CreateTokenReplacement(tok::equal, tok::equalequal,
- diag::err_invalid_equalequal_after_declarator) ||
- CreateTokenReplacement(tok::equal, tok::plusequal,
- diag::err_invalid_plusequal_after_declarator)) {
+ if (isTokenEqualOrEqualTypo()) {
ConsumeToken();
ExprResult AssignExpr(ParseAssignmentExpression());
if (!AssignExpr.isInvalid())
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 6342b10..45b4a74 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1401,21 +1401,31 @@
return false;
}
-bool Parser::CreateTokenReplacement(tok::TokenKind ExpectedToken,
- tok::TokenKind FoundToken,
- unsigned DiagID) {
- if (Tok.isNot(FoundToken))
+bool Parser::isTokenEqualOrEqualTypo() {
+ tok::TokenKind Kind = Tok.getKind();
+ switch (Kind) {
+ default:
return false;
-
- // We have FoundToken in a context that we would expect an ExpectedToken.
- // The user probably made a typo, intending to type ExpectedToken.
- // Emit diagnostic, fixit hint to turn ReplaceToken -> ExpectedToken
- // and continue as if the user typed ExpectedToken.
- Tok.setKind(ExpectedToken);
- Diag(Tok, DiagID)
- << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()),
- getTokenSimpleSpelling(ExpectedToken));
- return true;
+ case tok::ampequal: // &=
+ case tok::starequal: // *=
+ case tok::plusequal: // +=
+ case tok::minusequal: // -=
+ case tok::exclaimequal: // !=
+ case tok::slashequal: // /=
+ case tok::percentequal: // %=
+ case tok::lessequal: // <=
+ case tok::lesslessequal: // <<=
+ case tok::greaterequal: // >=
+ case tok::greatergreaterequal: // >>=
+ case tok::caretequal: // ^=
+ case tok::pipeequal: // |=
+ case tok::equalequal: // ==
+ Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
+ << getTokenSimpleSpelling(Kind)
+ << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
+ case tok::equal:
+ return true;
+ }
}
SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index 63726b9..8f7d14c 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -68,20 +68,68 @@
};
namespace rdar8488464 {
-int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
-int y += 0; // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
+int x = 0;
+int x1 &= 0; // expected-error {{invalid '&=' at end of declaration; did you mean '='?}}
+int x2 *= 0; // expected-error {{invalid '*=' at end of declaration; did you mean '='?}}
+int x3 += 0; // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
+int x4 -= 0; // expected-error {{invalid '-=' at end of declaration; did you mean '='?}}
+int x5 != 0; // expected-error {{invalid '!=' at end of declaration; did you mean '='?}}
+int x6 /= 0; // expected-error {{invalid '/=' at end of declaration; did you mean '='?}}
+int x7 %= 0; // expected-error {{invalid '%=' at end of declaration; did you mean '='?}}
+int x8 <= 0; // expected-error {{invalid '<=' at end of declaration; did you mean '='?}}
+int x9 <<= 0; // expected-error {{invalid '<<=' at end of declaration; did you mean '='?}}
+int x10 >= 0; // expected-error {{invalid '>=' at end of declaration; did you mean '='?}}
+int x11 >>= 0; // expected-error {{invalid '>>=' at end of declaration; did you mean '='?}}
+int x12 ^= 0; // expected-error {{invalid '^=' at end of declaration; did you mean '='?}}
+int x13 |= 0; // expected-error {{invalid '|=' at end of declaration; did you mean '='?}}
+int x14 == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
void f() {
- int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
+ int x = 0;
(void)x;
- int y += 0; // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
- (void)y;
- if (int x == 0) { // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
- (void)x;
- }
- if (int y += 0) { // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
- (void)y;
- }
+ int x1 &= 0; // expected-error {{invalid '&=' at end of declaration; did you mean '='?}}
+ (void)x1;
+ int x2 *= 0; // expected-error {{invalid '*=' at end of declaration; did you mean '='?}}
+ (void)x2;
+ int x3 += 0; // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
+ (void)x3;
+ int x4 -= 0; // expected-error {{invalid '-=' at end of declaration; did you mean '='?}}
+ (void)x4;
+ int x5 != 0; // expected-error {{invalid '!=' at end of declaration; did you mean '='?}}
+ (void)x5;
+ int x6 /= 0; // expected-error {{invalid '/=' at end of declaration; did you mean '='?}}
+ (void)x6;
+ int x7 %= 0; // expected-error {{invalid '%=' at end of declaration; did you mean '='?}}
+ (void)x7;
+ int x8 <= 0; // expected-error {{invalid '<=' at end of declaration; did you mean '='?}}
+ (void)x8;
+ int x9 <<= 0; // expected-error {{invalid '<<=' at end of declaration; did you mean '='?}}
+ (void)x9;
+ int x10 >= 0; // expected-error {{invalid '>=' at end of declaration; did you mean '='?}}
+ (void)x10;
+ int x11 >>= 0; // expected-error {{invalid '>>=' at end of declaration; did you mean '='?}}
+ (void)x11;
+ int x12 ^= 0; // expected-error {{invalid '^=' at end of declaration; did you mean '='?}}
+ (void)x12;
+ int x13 |= 0; // expected-error {{invalid '|=' at end of declaration; did you mean '='?}}
+ (void)x13;
+ int x14 == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
+ (void)x14;
+ if (int x = 0) { (void)x; }
+ if (int x1 &= 0) { (void)x1; } // expected-error {{invalid '&=' at end of declaration; did you mean '='?}}
+ if (int x2 *= 0) { (void)x2; } // expected-error {{invalid '*=' at end of declaration; did you mean '='?}}
+ if (int x3 += 0) { (void)x3; } // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
+ if (int x4 -= 0) { (void)x4; } // expected-error {{invalid '-=' at end of declaration; did you mean '='?}}
+ if (int x5 != 0) { (void)x5; } // expected-error {{invalid '!=' at end of declaration; did you mean '='?}}
+ if (int x6 /= 0) { (void)x6; } // expected-error {{invalid '/=' at end of declaration; did you mean '='?}}
+ if (int x7 %= 0) { (void)x7; } // expected-error {{invalid '%=' at end of declaration; did you mean '='?}}
+ if (int x8 <= 0) { (void)x8; } // expected-error {{invalid '<=' at end of declaration; did you mean '='?}}
+ if (int x9 <<= 0) { (void)x9; } // expected-error {{invalid '<<=' at end of declaration; did you mean '='?}}
+ if (int x10 >= 0) { (void)x10; } // expected-error {{invalid '>=' at end of declaration; did you mean '='?}}
+ if (int x11 >>= 0) { (void)x11; } // expected-error {{invalid '>>=' at end of declaration; did you mean '='?}}
+ if (int x12 ^= 0) { (void)x12; } // expected-error {{invalid '^=' at end of declaration; did you mean '='?}}
+ if (int x13 |= 0) { (void)x13; } // expected-error {{invalid '|=' at end of declaration; did you mean '='?}}
+ if (int x14 == 0) { (void)x14; } // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
}
}