Change the error when a '+=' follows a declaration to suggest a fixit to '=' instead of just suggesting a ';'.

Old error:
plusequaldeclare1.cc:3:8: error: expected ';' at end of declaration
  int x += 6;
       ^
       ;

New error:
plusequaldeclare1.cc:3:9: error: invalid '+=' at end of declaration; did you
      mean '='?
  int x += 6;
        ^~
        =

llvm-svn: 148433
This commit is contained in:
Richard Trieu 2012-01-18 22:54:52 +00:00
parent 94298a906a
commit c64d3230d2
6 changed files with 40 additions and 19 deletions

View File

@ -156,6 +156,8 @@ def err_invalid_token_after_toplevel_declarator : Error<
"expected ';' after top level declarator">; "expected ';' after top level declarator">;
def err_invalid_equalequal_after_declarator : Error< def err_invalid_equalequal_after_declarator : Error<
"invalid '==' at end of declaration; did you mean '='?">; "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_expected_statement : Error<"expected statement">; def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">; def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_lparen_after_id : Error<"expected '(' after %0">; def err_expected_lparen_after_id : Error<"expected '(' after %0">;

View File

@ -288,10 +288,12 @@ private:
Tok.getKind() == tok::utf32_string_literal; Tok.getKind() == tok::utf32_string_literal;
} }
/// \brief Returns true if the current token is a '=' or '==' and /// \brief Returns true if the current token is FoundToken. This token
/// false otherwise. If it's '==', we assume that it's a typo and we emit /// will be assumed a typo. A diagnostic will be emitted with DiagID with a
/// DiagID and a fixit hint to turn '==' -> '='. /// a fixit to replace the current token with ExpectedToken.
bool isTokenEqualOrMistypedEqualEqual(unsigned DiagID); bool CreateTokenReplacement(tok::TokenKind ExpectedToken,
tok::TokenKind FoundToken,
unsigned DiagID);
/// ConsumeToken - Consume the current 'peek token' and lex the next one. /// ConsumeToken - Consume the current 'peek token' and lex the next one.
/// This does not work with all kinds of tokens: strings and specific other /// This does not work with all kinds of tokens: strings and specific other

View File

@ -1269,8 +1269,12 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
// Parse declarator '=' initializer. // Parse declarator '=' initializer.
if (isTokenEqualOrMistypedEqualEqual( // If a '==' or '+=' is found, suggest a fixit to '='.
diag::err_invalid_equalequal_after_declarator)) { 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)) {
ConsumeToken(); ConsumeToken();
if (Tok.is(tok::kw_delete)) { if (Tok.is(tok::kw_delete)) {
if (D.isFunctionDeclarator()) if (D.isFunctionDeclarator())

View File

@ -1259,8 +1259,12 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
ExprOut = ExprError(); ExprOut = ExprError();
// '=' assignment-expression // '=' assignment-expression
if (isTokenEqualOrMistypedEqualEqual( // If a '==' or '+=' is found, suggest a fixit to '='.
diag::err_invalid_equalequal_after_declarator)) { 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)) {
ConsumeToken(); ConsumeToken();
ExprResult AssignExpr(ParseAssignmentExpression()); ExprResult AssignExpr(ParseAssignmentExpression());
if (!AssignExpr.isInvalid()) if (!AssignExpr.isInvalid())

View File

@ -1401,18 +1401,21 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
return false; return false;
} }
bool Parser::isTokenEqualOrMistypedEqualEqual(unsigned DiagID) { bool Parser::CreateTokenReplacement(tok::TokenKind ExpectedToken,
if (Tok.is(tok::equalequal)) { tok::TokenKind FoundToken,
// We have '==' in a context that we would expect a '='. unsigned DiagID) {
// The user probably made a typo, intending to type '='. Emit diagnostic, if (Tok.isNot(FoundToken))
// fixit hint to turn '==' -> '=' and continue as if the user typed '='. return false;
Diag(Tok, DiagID)
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()),
getTokenSimpleSpelling(tok::equal));
return true;
}
return Tok.is(tok::equal); // 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;
} }
SourceLocation Parser::handleUnexpectedCodeCompletionToken() { SourceLocation Parser::handleUnexpectedCodeCompletionToken() {

View File

@ -69,13 +69,19 @@ class C {
namespace rdar8488464 { namespace rdar8488464 {
int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}} 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 '='?}}
void f() { void f() {
int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}} int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
(void)x; (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 '='?}} if (int x == 0) { // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
(void)x; (void)x;
} }
if (int y += 0) { // expected-error {{invalid '+=' at end of declaration; did you mean '='?}}
(void)y;
}
} }
} }