[cfe-commits] PATCH: Restart handling of a function declarator if the function name was typo-corrected (issue 4929043)
rikka at google.com
rikka at google.com
Fri Aug 19 13:47:05 PDT 2011
Reviewers: chandlerc,
Description:
Not sure if this is the right way (without a major rewrite of
Sema::CorrectTypo and friends) to achieve the goal, but it solves the
issue brought up by Jordy in response to r137966 where an out-of-line
function definition is not rechecked against existing declarations to
see if it is valid after being typo-corrected.
Please review this at http://codereview.appspot.com/4929043/
Affected files:
M lib/Sema/SemaDecl.cpp
M test/SemaCXX/function-redecl.cpp
-------------- next part --------------
Index: test/SemaCXX/function-redecl.cpp
===================================================================
--- test/SemaCXX/function-redecl.cpp (revision 138068)
+++ test/SemaCXX/function-redecl.cpp (working copy)
@@ -54,3 +54,8 @@
struct X { int f(); };
struct Y : public X {};
int Y::f() { return 3; } // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Y'}}
+
+struct J { int typo() const; }; // expected-note {{'typo' declared here}} \
+ // expected-note {{member declaration nearly matches}}
+int J::typo_() { return 3; } // expected-error {{out-of-line definition of 'typo_' does not match any declaration in 'J'; did you mean 'typo'}} \
+ // expected-error {{out-of-line definition of 'typo' does not match any declaration in 'J'}}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp (revision 138068)
+++ lib/Sema/SemaDecl.cpp (working copy)
@@ -4204,7 +4204,8 @@
return AddedAny;
}
-static void DiagnoseInvalidRedeclaration(Sema &S, FunctionDecl *NewFD,
+static bool DiagnoseInvalidRedeclaration(Sema &S, LookupResult &Previous,
+ FunctionDecl *NewFD,
bool isFriendDecl) {
DeclarationName Name = NewFD->getDeclName();
DeclContext *DC = NewFD->getDeclContext();
@@ -4213,6 +4214,7 @@
llvm::SmallVector<unsigned, 1> MismatchedParams;
llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1> NearMatches;
TypoCorrection Correction;
+ bool TypoWasCorrected = false;
unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend
: diag::err_member_def_does_not_match;
@@ -4239,6 +4241,9 @@
Correction.getCorrection() != Name) {
DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend_suggest
: diag::err_member_def_does_not_match_suggest;
+ TypoWasCorrected = true;
+ Previous.clear();
+ Previous.setLookupName(Correction.getCorrection());
for (TypoCorrection::decl_iterator CDecl = Correction.begin(),
CDeclEnd = Correction.end();
CDecl != CDeclEnd; ++CDecl) {
@@ -4250,11 +4255,12 @@
unsigned ParamNum =
MismatchedParams.empty() ? 0 : MismatchedParams.front() + 1;
NearMatches.push_back(std::make_pair(FD, ParamNum));
+ Previous.addDecl(FD);
}
}
}
- if (Correction)
+ if (TypoWasCorrected)
S.Diag(NewFD->getLocation(), DiagMsg)
<< Name << DC << Correction.getQuoted(S.getLangOptions())
<< FixItHint::CreateReplacement(
@@ -4278,6 +4284,7 @@
} else
S.Diag(FD->getLocation(), diag::note_member_def_close_match);
}
+ return TypoWasCorrected;
}
NamedDecl*
@@ -4992,13 +4999,27 @@
// matches (e.g., those that differ only in cv-qualifiers and
// whether the parameter types are references).
- DiagnoseInvalidRedeclaration(*this, NewFD, false);
+ if (DiagnoseInvalidRedeclaration(*this, Previous, NewFD, false)) {
+ D.SetIdentifier(Previous.getLookupName().getAsIdentifierInfo(),
+ D.getIdentifierLoc());
+ return ActOnFunctionDeclarator(S, D, DC, R, TInfo, Previous,
+ TemplateParamLists,
+ IsFunctionDefinition,
+ Redeclaration, AddToScope);
+ }
}
// Unqualified local friend declarations are required to resolve
// to something.
} else if (isFriend && cast<CXXRecordDecl>(CurContext)->isLocalClass()) {
- DiagnoseInvalidRedeclaration(*this, NewFD, true);
+ if (DiagnoseInvalidRedeclaration(*this, Previous, NewFD, true)) {
+ D.SetIdentifier(Previous.getLookupName().getAsIdentifierInfo(),
+ D.getIdentifierLoc());
+ return ActOnFunctionDeclarator(S, D, DC, R, TInfo, Previous,
+ TemplateParamLists,
+ IsFunctionDefinition, Redeclaration,
+ AddToScope);
+ }
}
} else if (!IsFunctionDefinition && D.getCXXScopeSpec().isSet() &&
More information about the cfe-commits
mailing list