Skip to content

Commit b5c7c51

Browse files
committed
When we encounter a '==' in a context expecting a '=', assume the user made a typo:
t.c:1:7: error: invalid '==' at end of declaration; did you mean '='? int x == 0; ^~ = Implements rdar://8488464. llvm-svn: 116035
1 parent d4e9c3b commit b5c7c51

File tree

6 files changed

+38
-3
lines changed

6 files changed

+38
-3
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ def err_expected_fn_body : Error<
112112
def err_expected_method_body : Error<"expected method body">;
113113
def err_invalid_token_after_toplevel_declarator : Error<
114114
"expected ';' after top level declarator">;
115+
def err_invalid_equalequal_after_declarator : Error<
116+
"invalid '==' at end of declaration; did you mean '='?">;
115117
def err_expected_statement : Error<"expected statement">;
116118
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
117119
def err_expected_lparen_after_id : Error<"expected '(' after %0">;

clang/include/clang/Parse/Parser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ class Parser : public CodeCompletionHandler {
236236
Tok.getKind() == tok::wide_string_literal;
237237
}
238238

239+
/// \brief Returns true if the current token is a '=' or '==' and
240+
/// false otherwise. If it's '==', we assume that it's a typo and we emit
241+
/// DiagID and a fixit hint to turn '==' -> '='.
242+
bool isTokenEqualOrMistypedEqualEqual(unsigned DiagID);
243+
239244
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
240245
/// This does not work with all kinds of tokens: strings and specific other
241246
/// tokens must be consumed with custom methods below. This returns the

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,8 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
594594
}
595595

596596
// Parse declarator '=' initializer.
597-
if (Tok.is(tok::equal)) {
597+
if (isTokenEqualOrMistypedEqualEqual(
598+
diag::err_invalid_equalequal_after_declarator)) {
598599
ConsumeToken();
599600
if (Tok.is(tok::kw_delete)) {
600601
SourceLocation DelLoc = ConsumeToken();

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,10 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
821821
DeclaratorInfo);
822822
DeclOut = Dcl.get();
823823
ExprOut = ExprError();
824-
824+
825825
// '=' assignment-expression
826-
if (Tok.is(tok::equal)) {
826+
if (isTokenEqualOrMistypedEqualEqual(
827+
diag::err_invalid_equalequal_after_declarator)) {
827828
SourceLocation EqualLoc = ConsumeToken();
828829
ExprResult AssignExpr(ParseAssignmentExpression());
829830
if (!AssignExpr.isInvalid())

clang/lib/Parse/Parser.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,20 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
11561156
return false;
11571157
}
11581158

1159+
bool Parser::isTokenEqualOrMistypedEqualEqual(unsigned DiagID) {
1160+
if (Tok.is(tok::equalequal)) {
1161+
// We have '==' in a context that we would expect a '='.
1162+
// The user probably made a typo, intending to type '='. Emit diagnostic,
1163+
// fixit hint to turn '==' -> '=' and continue as if the user typed '='.
1164+
Diag(Tok, DiagID)
1165+
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()),
1166+
getTokenSimpleSpelling(tok::equal));
1167+
return true;
1168+
}
1169+
1170+
return Tok.is(tok::equal);
1171+
}
1172+
11591173
void Parser::CodeCompletionRecovery() {
11601174
for (Scope *S = getCurScope(); S; S = S->getParent()) {
11611175
if (S->getFlags() & Scope::FnScope) {

clang/test/FixIt/fixit.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,15 @@ class C {
7171
int C::foo();
7272
};
7373

74+
namespace rdar8488464 {
75+
int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
76+
77+
void f() {
78+
int x == 0; // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
79+
(void)x;
80+
if (int x == 0) { // expected-error {{invalid '==' at end of declaration; did you mean '='?}}
81+
(void)x;
82+
}
83+
}
84+
}
85+

0 commit comments

Comments
 (0)