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 '='?}}
 }
 }