aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2011-11-14 23:30:34 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2011-11-14 23:30:34 +0000
commita70cb9db9dd79ca9fc1febbb2f331004297664e0 (patch)
tree88e5813d2db229f6769dc39bc0f2e1f6a232da91
parente1ba5be96e57738ba0d6302cdb471e12107a3201 (diff)
Print a typo correction hint for unknown warning flags.
$ clang -Wololo t.c warning: unknown warning option '-Wololo'; did you mean '-Wall'? [-Wunknown-warning-option] git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144591 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticIDs.h4
-rw-r--r--lib/Basic/DiagnosticIDs.cpp21
-rw-r--r--lib/Frontend/Warnings.cpp11
-rw-r--r--test/Driver/cc-log-diagnostics.c2
5 files changed, 36 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index c9f5a5c486..91e32200f2 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -148,10 +148,10 @@ def warn_pch_compiler_options_mismatch : Error<
def err_not_a_pch_file : Error<
"'%0' does not appear to be a precompiled header file">, DefaultFatal;
def warn_unknown_warning_option : Warning<
- "unknown warning option '%0'">,
+ "unknown warning option '%0'; did you mean '%1'?">,
InGroup<DiagGroup<"unknown-warning-option"> >;
def warn_unknown_negative_warning_option : Warning<
- "unknown warning option '%0'">,
+ "unknown warning option '%0'; did you mean '%1'?">,
InGroup<DiagGroup<"unknown-warning-option"> >, DefaultIgnore;
def warn_unknown_warning_specifier : Warning<
"unknown %0 warning specifier: '%1'">,
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 1ff6c11924..da85ea491b 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -262,6 +262,10 @@ public:
bool getDiagnosticsInGroup(StringRef Group,
llvm::SmallVectorImpl<diag::kind> &Diags) const;
+ /// \brief Get the warning option with the closest edit distance to the given
+ /// group name.
+ static StringRef getNearestWarningOption(StringRef Group);
+
private:
/// \brief Get the set of all diagnostic IDs in the given group.
///
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index b14cdc9ba3..39fee69adb 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -681,6 +681,27 @@ bool DiagnosticIDs::getDiagnosticsInGroup(
return false;
}
+StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
+ StringRef Best;
+ unsigned BestDistance = 0;
+ for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
+ i != e; ++i) {
+ // Don't suggest ignored warning flags.
+ if (!i->Members && !i->SubGroups)
+ continue;
+
+ unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
+
+ // Check if this is a better match.
+ if (Best.empty() || Distance < BestDistance) {
+ Best = i->getName();
+ BestDistance = Distance;
+ }
+ }
+
+ return Best;
+}
+
/// ProcessDiag - This is the method used to report a diagnostic that is
/// finally fully formed.
bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
index 7fcbe3acd4..ba0cd38045 100644
--- a/lib/Frontend/Warnings.cpp
+++ b/lib/Frontend/Warnings.cpp
@@ -120,7 +120,9 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
} else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
Diags.Report(isPositive ? diag::warn_unknown_warning_option :
diag::warn_unknown_negative_warning_option)
- << ("-W" + Opt.str());
+ << ("-W" + Opt.str())
+ << ("-Werror=" +
+ DiagnosticIDs::getNearestWarningOption(Specifier).str());
}
continue;
}
@@ -150,7 +152,9 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
} else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
Diags.Report(isPositive ? diag::warn_unknown_warning_option :
diag::warn_unknown_negative_warning_option)
- << ("-W" + Opt.str());
+ << ("-W" + Opt.str())
+ << ("-Wfatal-errors=" +
+ DiagnosticIDs::getNearestWarningOption(Specifier).str());
}
continue;
}
@@ -158,7 +162,8 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
if (Report && DiagIDs->getDiagnosticsInGroup(Opt, _Diags)) {
Diags.Report(isPositive ? diag::warn_unknown_warning_option :
diag::warn_unknown_negative_warning_option)
- << ("-W" + Opt.str());
+ << ("-W" + Opt.str())
+ << ("-W" + DiagnosticIDs::getNearestWarningOption(Opt).str());
} else {
Diags.setDiagnosticGroupMapping(Opt, Mapping);
}
diff --git a/test/Driver/cc-log-diagnostics.c b/test/Driver/cc-log-diagnostics.c
index 2fdbe5133c..96b2ec3e5d 100644
--- a/test/Driver/cc-log-diagnostics.c
+++ b/test/Driver/cc-log-diagnostics.c
@@ -17,7 +17,7 @@ int f0() {}
// CHECK: <key>level</key>
// CHECK: <string>warning</string>
// CHECK: <key>message</key>
-// CHECK: <string>unknown warning option &apos;-Wfoobar&apos;</string>
+// CHECK: <string>unknown warning option &apos;-Wfoobar&apos;; did you mean &apos;-W{{.*}}&apos;?</string>
// CHECK: </dict>
// CHECK: <dict>
// CHECK: <key>level</key>