]> granicus.if.org Git - clang/commitdiff
Warning option typo correction: When two options have the same edit_distance don...
authorBenjamin Kramer <benny.kra@googlemail.com>
Tue, 15 Nov 2011 12:26:39 +0000 (12:26 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Tue, 15 Nov 2011 12:26:39 +0000 (12:26 +0000)
Also add a maximum edit distance threshold, so we don't correct "-Wx" to "-W#pragma-messages".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144644 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticFrontendKinds.td
lib/Basic/DiagnosticIDs.cpp
lib/Frontend/Warnings.cpp

index 91e32200f2f7a6042ba6a02dec677458a6a0ebec..857f77e85506044ec7e9c7968bf19531cf4a28f2 100644 (file)
@@ -148,9 +148,15 @@ 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'; did you mean '%1'?">,
+    "unknown warning option '%0'">,
     InGroup<DiagGroup<"unknown-warning-option"> >;
 def warn_unknown_negative_warning_option : Warning<
+    "unknown warning option '%0'?">,
+    InGroup<DiagGroup<"unknown-warning-option"> >, DefaultIgnore;
+def warn_unknown_warning_option_suggest : Warning<
+    "unknown warning option '%0'; did you mean '%1'?">,
+    InGroup<DiagGroup<"unknown-warning-option"> >;
+def warn_unknown_negative_warning_option_suggest : Warning<
     "unknown warning option '%0'; did you mean '%1'?">,
     InGroup<DiagGroup<"unknown-warning-option"> >, DefaultIgnore;
 def warn_unknown_warning_specifier : Warning<
index 39fee69adbef28b3ec7a109326a3b20b8a9dc0d4..cbca8d1c7697f9d6d8b3eaf156c57f67f1b976fc 100644 (file)
@@ -683,7 +683,7 @@ bool DiagnosticIDs::getDiagnosticsInGroup(
 
 StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
   StringRef Best;
-  unsigned BestDistance = 0;
+  unsigned BestDistance = Group.size() + 1; // Sanity threshold.
   for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
        i != e; ++i) {
     // Don't suggest ignored warning flags.
@@ -691,9 +691,11 @@ StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
       continue;
 
     unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
-
-    // Check if this is a better match.
-    if (Best.empty() || Distance < BestDistance) {
+    if (Distance == BestDistance) {
+      // Two matches with the same distance, don't prefer one over the other.
+      Best = "";
+    } else if (Distance < BestDistance) {
+      // This is a better match.
       Best = i->getName();
       BestDistance = Distance;
     }
index ba0cd38045c68c6988582eedc1d6554dc402fa16..4e41e22138c7ddfbe97b1795a8fd348555b27a97 100644 (file)
 #include <algorithm>
 using namespace clang;
 
+// EmitUnkownDiagWarning - Emit a warning and typo hint for unknown warning opts
+static void EmitUnkownDiagWarning(DiagnosticsEngine &Diags,
+                                  StringRef Prefix, StringRef Opt,
+                                  bool isPositive) {
+  StringRef Suggestion = DiagnosticIDs::getNearestWarningOption(Opt);
+  if (!Suggestion.empty())
+    Diags.Report(isPositive? diag::warn_unknown_warning_option_suggest :
+                             diag::warn_unknown_negative_warning_option_suggest)
+      << (Prefix.str() += Opt) << (Prefix.str() += Suggestion);
+  else
+    Diags.Report(isPositive? diag::warn_unknown_warning_option :
+                             diag::warn_unknown_negative_warning_option)
+      << (Prefix.str() += Opt);
+}
+
 void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
                                   const DiagnosticOptions &Opts) {
   Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
@@ -118,11 +133,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
           // Set the warning as error flag for this specifier.
           Diags.setDiagnosticGroupWarningAsError(Specifier, isPositive);
         } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          Diags.Report(isPositive ? diag::warn_unknown_warning_option :
-                       diag::warn_unknown_negative_warning_option)
-            << ("-W" + Opt.str())
-            << ("-Werror=" +
-                DiagnosticIDs::getNearestWarningOption(Specifier).str());
+          EmitUnkownDiagWarning(Diags, "-Werror", Specifier, isPositive);
         }
         continue;
       }
@@ -150,20 +161,13 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
           // Set the error as fatal flag for this specifier.
           Diags.setDiagnosticGroupErrorAsFatal(Specifier, isPositive);
         } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          Diags.Report(isPositive ? diag::warn_unknown_warning_option :
-                       diag::warn_unknown_negative_warning_option)
-            << ("-W" + Opt.str())
-            << ("-Wfatal-errors=" +
-                DiagnosticIDs::getNearestWarningOption(Specifier).str());
+          EmitUnkownDiagWarning(Diags, "-Wfatal-errors", Specifier, isPositive);
         }
         continue;
       }
       
       if (Report && DiagIDs->getDiagnosticsInGroup(Opt, _Diags)) {
-        Diags.Report(isPositive ? diag::warn_unknown_warning_option :
-                     diag::warn_unknown_negative_warning_option)
-          << ("-W" + Opt.str())
-          << ("-W" + DiagnosticIDs::getNearestWarningOption(Opt).str());
+        EmitUnkownDiagWarning(Diags, "-W", Opt, isPositive);
       } else {
         Diags.setDiagnosticGroupMapping(Opt, Mapping);
       }