r321917 - [Driver] Suggest correctly spelled driver options

Brian Gesiak via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 5 16:25:40 PST 2018


Author: modocache
Date: Fri Jan  5 16:25:40 2018
New Revision: 321917

URL: http://llvm.org/viewvc/llvm-project?rev=321917&view=rev
Log:
[Driver] Suggest correctly spelled driver options

Summary:
Depends on https://reviews.llvm.org/D41732.

Utilities such as `opt`, when invoked with arguments that are very
nearly spelled correctly, suggest the correctly spelled options:

```
bin/opt -hel
opt: Unknown command line argument '-hel'.  Try: 'bin/opt -help'
opt: Did you mean '-help'?
```

Clang, on the other hand, prior to this commit, does not:

```
bin/clang -hel
clang-6.0: error: unknown argument: '-hel'
```

This commit makes use of the new libLLVMOption API from
https://reviews.llvm.org/D41732 in order to provide correct suggestions:

```
bin/clang -hel
clang-6.0: error: unknown argument: '-hel', did you mean '-help'?
```

Test Plan: `check-clang`

Reviewers: yamaguchi, v.g.vassilev, teemperor, ruiu, bruno

Reviewed By: bruno

Subscribers: bruno, jroelofs, cfe-commits

Differential Revision: https://reviews.llvm.org/D41733

Added:
    cfe/trunk/test/Driver/unsupported-option.c
    cfe/trunk/test/Frontend/unknown-arg.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/test/Driver/unknown-arg.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=321917&r1=321916&r2=321917&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Fri Jan  5 16:25:40 2018
@@ -11,6 +11,8 @@ let Component = "Driver" in {
 
 def err_drv_no_such_file : Error<"no such file or directory: '%0'">;
 def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
+def err_drv_unsupported_opt_with_suggestion
+  : Error<"unsupported option '%0', did you mean '%1'?">;
 def err_drv_unsupported_opt_for_target : Error<
   "unsupported option '%0' for target '%1'">;
 def err_drv_unsupported_option_argument : Error<
@@ -135,9 +137,14 @@ def err_arch_unsupported_isa
 def err_drv_I_dash_not_supported : Error<
   "'%0' not supported, please use -iquote instead">;
 def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
+def err_drv_unknown_argument_with_suggestion
+  : Error<"unknown argument '%0', did you mean '%1'?">;
 def warn_drv_unknown_argument_clang_cl : Warning<
   "unknown argument ignored in clang-cl: '%0'">,
   InGroup<UnknownArgument>;
+def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning<
+  "unknown argument ignored in clang-cl '%0' (did you mean '%1'?)">,
+  InGroup<UnknownArgument>;
 
 def warn_drv_ycyu_no_arg_clang_cl : Warning<
   "support for '%0' without a filename not implemented yet; flag ignored">,

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=321917&r1=321916&r2=321917&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Fri Jan  5 16:25:40 2018
@@ -188,9 +188,19 @@ InputArgList Driver::ParseArgStrings(Arr
   // Check for unsupported options.
   for (const Arg *A : Args) {
     if (A->getOption().hasFlag(options::Unsupported)) {
-      Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
-      ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
-                                                SourceLocation()) >
+      unsigned DiagID;
+      auto ArgString = A->getAsString(Args);
+      std::string Nearest;
+      if (getOpts().findNearest(
+            ArgString, Nearest, IncludedFlagsBitmask,
+            ExcludedFlagsBitmask | options::Unsupported) > 1) {
+        DiagID = diag::err_drv_unsupported_opt;
+        Diag(DiagID) << ArgString;
+      } else {
+        DiagID = diag::err_drv_unsupported_opt_with_suggestion;
+        Diag(DiagID) << ArgString << Nearest;
+      }
+      ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
                        DiagnosticsEngine::Warning;
       continue;
     }
@@ -205,11 +215,20 @@ InputArgList Driver::ParseArgStrings(Arr
   }
 
   for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
-    auto ID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
-                         : diag::err_drv_unknown_argument;
-
-    Diags.Report(ID) << A->getAsString(Args);
-    ContainsError |= Diags.getDiagnosticLevel(ID, SourceLocation()) >
+    unsigned DiagID;
+    auto ArgString = A->getAsString(Args);
+    std::string Nearest;
+    if (getOpts().findNearest(
+          ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) {
+      DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
+                          : diag::err_drv_unknown_argument;
+      Diags.Report(DiagID) << ArgString;
+    } else {
+      DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
+                          : diag::err_drv_unknown_argument_with_suggestion;
+      Diags.Report(DiagID) << ArgString << Nearest;
+    }
+    ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
                      DiagnosticsEngine::Warning;
   }
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=321917&r1=321916&r2=321917&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Jan  5 16:25:40 2018
@@ -2757,7 +2757,13 @@ bool CompilerInvocation::CreateFromArgs(
 
   // Issue errors on unknown arguments.
   for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
-    Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
+    auto ArgString = A->getAsString(Args);
+    std::string Nearest;
+    if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
+      Diags.Report(diag::err_drv_unknown_argument) << ArgString;
+    else
+      Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
+          << ArgString << Nearest;
     Success = false;
   }
 

Modified: cfe/trunk/test/Driver/unknown-arg.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/unknown-arg.c?rev=321917&r1=321916&r2=321917&view=diff
==============================================================================
--- cfe/trunk/test/Driver/unknown-arg.c (original)
+++ cfe/trunk/test/Driver/unknown-arg.c Fri Jan  5 16:25:40 2018
@@ -1,9 +1,15 @@
 // RUN: not %clang %s -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -### 2>&1 | \
 // RUN: FileCheck %s
+// RUN: not %clang %s -stdlibs=foo -hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -### -c -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL
+// RUN: %clang_cl -Brepo -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-DID-YOU-MEAN
 // RUN: not %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Werror=unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL-ERROR
+// RUN: not %clang_cl -helo -Werror=unknown-argument -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-ERROR-DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d -HHHH -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Wno-unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=SILENT
 
@@ -14,6 +20,8 @@
 // CHECK: error: unknown argument: '-munknown-to-clang-option'
 // CHECK: error: unknown argument: '-print-stats'
 // CHECK: error: unknown argument: '-funknown-to-clang-option'
+// DID-YOU-MEAN: error: unknown argument '-stdlibs=foo', did you mean '-stdlib=foo'?
+// DID-YOU-MEAN: error: unknown argument '-hell', did you mean '-help'?
 // CL: warning: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL: warning: unknown argument ignored in clang-cl: '-%0'
 // CL: warning: unknown argument ignored in clang-cl: '-%d'
@@ -21,6 +29,7 @@
 // CL: warning: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL: warning: unknown argument ignored in clang-cl: '-print-stats'
 // CL: warning: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-DID-YOU-MEAN: warning: unknown argument ignored in clang-cl '-Brepo' (did you mean '-Brepro'?)
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%0'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%d'
@@ -28,6 +37,7 @@
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-print-stats'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-ERROR-DID-YOU-MEAN: error: unknown argument ignored in clang-cl '-helo' (did you mean '-help'?)
 // SILENT-NOT: error:
 // SILENT-NOT: warning:
 

Added: cfe/trunk/test/Driver/unsupported-option.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/unsupported-option.c?rev=321917&view=auto
==============================================================================
--- cfe/trunk/test/Driver/unsupported-option.c (added)
+++ cfe/trunk/test/Driver/unsupported-option.c Fri Jan  5 16:25:40 2018
@@ -0,0 +1,7 @@
+// RUN: not %clang %s --hedonism -### 2>&1 | \
+// RUN: FileCheck %s
+// RUN: not %clang %s --hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+
+// CHECK: error: unsupported option '--hedonism'
+// DID-YOU-MEAN: error: unsupported option '--hell', did you mean '--help'?

Added: cfe/trunk/test/Frontend/unknown-arg.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/unknown-arg.c?rev=321917&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/unknown-arg.c (added)
+++ cfe/trunk/test/Frontend/unknown-arg.c Fri Jan  5 16:25:40 2018
@@ -0,0 +1,9 @@
+// RUN: not %clang_cc1 %s -E --helium 2>&1 | \
+// RUN: FileCheck %s
+// RUN: not %clang_cc1 %s -E --hel[ 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+// RUN: not %clang %s -E -Xclang --hel[ 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+
+// CHECK: error: unknown argument: '--helium'
+// DID-YOU-MEAN: error: unknown argument '--hel[', did you mean '--help'?




More information about the cfe-commits mailing list