[cfe-commits] r137966 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaCXX/function-redecl.cpp
Kaelyn Uhrain
rikka at google.com
Thu Aug 18 11:19:12 PDT 2011
Author: rikka
Date: Thu Aug 18 13:19:12 2011
New Revision: 137966
URL: http://llvm.org/viewvc/llvm-project?rev=137966&view=rev
Log:
Rework DiagnoseInvalidRedeclaration to add the ability to correct typos when
diagnosing invalid function redeclarations.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/SemaCXX/function-redecl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=137966&r1=137965&r2=137966&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Aug 18 13:19:12 2011
@@ -610,6 +610,8 @@
"friend type templates must use an elaborated type">;
def err_no_matching_local_friend : Error<
"no matching function found in local scope">;
+def err_no_matching_local_friend_suggest : Error<
+ "no matching function %0 found in local scope; did you mean %2">;
def err_partial_specialization_friend : Error<
"partial specialization cannot be declared as a friend">;
@@ -3038,6 +3040,9 @@
"out-of-line definition of %0 from class %1 without definition">;
def err_member_def_does_not_match : Error<
"out-of-line definition of %0 does not match any declaration in %1">;
+def err_member_def_does_not_match_suggest : Error<
+ "out-of-line definition of %0 does not match any declaration in %1; "
+ "did you mean %2">;
def err_member_def_does_not_match_ret_type : Error<
"out-of-line definition of %q0 differs from the declaration in the return type">;
def err_nonstatic_member_out_of_line : Error<
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=137966&r1=137965&r2=137966&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Aug 18 13:19:12 2011
@@ -4204,28 +4204,79 @@
return AddedAny;
}
-static void DiagnoseInvalidRedeclaration(Sema &S, FunctionDecl *NewFD) {
- LookupResult Prev(S, NewFD->getDeclName(), NewFD->getLocation(),
+static void DiagnoseInvalidRedeclaration(Sema &S, FunctionDecl *NewFD,
+ bool isFriendDecl) {
+ DeclarationName Name = NewFD->getDeclName();
+ DeclContext *DC = NewFD->getDeclContext();
+ LookupResult Prev(S, Name, NewFD->getLocation(),
Sema::LookupOrdinaryName, Sema::ForRedeclaration);
llvm::SmallVector<unsigned, 1> MismatchedParams;
- S.LookupQualifiedName(Prev, NewFD->getDeclContext());
+ llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1> NearMatches;
+ TypoCorrection Correction;
+ unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend
+ : diag::err_member_def_does_not_match;
+
+ NewFD->setInvalidDecl();
+ S.LookupQualifiedName(Prev, DC);
assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup");
- for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
- Func != FuncEnd; ++Func) {
- FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func);
- if (FD && isNearlyMatchingFunction(S.Context, FD, NewFD,
- MismatchedParams)) {
- if (MismatchedParams.size() > 0) {
- unsigned Idx = MismatchedParams.front();
- ParmVarDecl *FDParam = FD->getParamDecl(Idx);
- S.Diag(FDParam->getTypeSpecStartLoc(),
- diag::note_member_def_close_param_match)
- << Idx+1 << FDParam->getType() << NewFD->getParamDecl(Idx)->getType();
- } else
- S.Diag(FD->getLocation(), diag::note_member_def_close_match);
+ if (!Prev.empty()) {
+ for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
+ Func != FuncEnd; ++Func) {
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func);
+ if (FD && isNearlyMatchingFunction(S.Context, FD, NewFD,
+ MismatchedParams)) {
+ // Add 1 to the index so that 0 can mean the mismatch didn't
+ // involve a parameter
+ unsigned ParamNum =
+ MismatchedParams.empty() ? 0 : MismatchedParams.front() + 1;
+ NearMatches.push_back(std::make_pair(FD, ParamNum));
+ }
+ }
+ // If the qualified name lookup yielded nothing, try typo correction
+ } else if ((Correction = S.CorrectTypo(Prev.getLookupNameInfo(),
+ Prev.getLookupKind(), 0, 0, DC))) {
+ DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend_suggest
+ : diag::err_member_def_does_not_match_suggest;
+ for (TypoCorrection::decl_iterator CDecl = Correction.begin(),
+ CDeclEnd = Correction.end();
+ CDecl != CDeclEnd; ++CDecl) {
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(*CDecl);
+ if (FD && isNearlyMatchingFunction(S.Context, FD, NewFD,
+ MismatchedParams)) {
+ // Add 1 to the index so that 0 can mean the mismatch didn't
+ // involve a parameter
+ unsigned ParamNum =
+ MismatchedParams.empty() ? 0 : MismatchedParams.front() + 1;
+ NearMatches.push_back(std::make_pair(FD, ParamNum));
+ }
}
}
+
+ if (Correction)
+ S.Diag(NewFD->getLocation(), DiagMsg)
+ << Name << DC << Correction.getQuoted(S.getLangOptions())
+ << FixItHint::CreateReplacement(
+ NewFD->getLocation(), Correction.getAsString(S.getLangOptions()));
+ else
+ S.Diag(NewFD->getLocation(), DiagMsg) << Name << DC << NewFD->getLocation();
+
+ for (llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1>::iterator
+ NearMatch = NearMatches.begin(), NearMatchEnd = NearMatches.end();
+ NearMatch != NearMatchEnd; ++NearMatch) {
+ FunctionDecl *FD = NearMatch->first;
+
+ if (unsigned Idx = NearMatch->second) {
+ ParmVarDecl *FDParam = FD->getParamDecl(Idx-1);
+ S.Diag(FDParam->getTypeSpecStartLoc(),
+ diag::note_member_def_close_param_match)
+ << Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType();
+ } else if (Correction) {
+ S.Diag(FD->getLocation(), diag::note_previous_decl)
+ << Correction.getQuoted(S.getLangOptions());
+ } else
+ S.Diag(FD->getLocation(), diag::note_member_def_close_match);
+ }
}
NamedDecl*
@@ -4939,19 +4990,14 @@
// Complain about this problem, and attempt to suggest close
// matches (e.g., those that differ only in cv-qualifiers and
// whether the parameter types are references).
- Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
- << Name << DC << D.getCXXScopeSpec().getRange();
- NewFD->setInvalidDecl();
- DiagnoseInvalidRedeclaration(*this, NewFD);
+ DiagnoseInvalidRedeclaration(*this, NewFD, false);
}
// Unqualified local friend declarations are required to resolve
// to something.
} else if (isFriend && cast<CXXRecordDecl>(CurContext)->isLocalClass()) {
- Diag(D.getIdentifierLoc(), diag::err_no_matching_local_friend);
- NewFD->setInvalidDecl();
- DiagnoseInvalidRedeclaration(*this, NewFD);
+ DiagnoseInvalidRedeclaration(*this, NewFD, true);
}
} else if (!IsFunctionDefinition && D.getCXXScopeSpec().isSet() &&
Modified: cfe/trunk/test/SemaCXX/function-redecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-redecl.cpp?rev=137966&r1=137965&r2=137966&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/function-redecl.cpp (original)
+++ cfe/trunk/test/SemaCXX/function-redecl.cpp Thu Aug 18 13:19:12 2011
@@ -24,3 +24,29 @@
}
}
}
+
+class A {
+ void typocorrection(); // expected-note {{'typocorrection' declared here}}
+};
+
+void A::Notypocorrection() { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'A'; did you mean 'typocorrection'}}
+}
+
+
+namespace test0 {
+ void dummy() {
+ void Bar(); // expected-note {{'Bar' declared here}}
+ class A {
+ friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean 'Bar'}}
+ };
+ }
+}
+
+
+class B {
+ void typocorrection(const int); // expected-note {{type of 1st parameter of member declaration does not match definition}}
+ void typocorrection(double);
+};
+
+void B::Notypocorrection(int) { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'B'; did you mean 'typocorrection'}}
+}
More information about the cfe-commits
mailing list