summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBrian Gesiak <modocache@gmail.com>2018-01-06 00:25:40 +0000
committerBrian Gesiak <modocache@gmail.com>2018-01-06 00:25:40 +0000
commit24910765e266a4344fa2993a2c5f3fdd9bfb19eb (patch)
treea034946598a9f85cfad2bdf4f20e80aaa997b2e0 /clang
parent041740ff69b1a7d0393f511c52587274cc3abd0a (diff)
downloadbcm5719-llvm-24910765e266a4344fa2993a2c5f3fdd9bfb19eb.tar.gz
bcm5719-llvm-24910765e266a4344fa2993a2c5f3fdd9bfb19eb.zip
[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 llvm-svn: 321917
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td7
-rw-r--r--clang/lib/Driver/Driver.cpp35
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp8
-rw-r--r--clang/test/Driver/unknown-arg.c10
-rw-r--r--clang/test/Driver/unsupported-option.c7
-rw-r--r--clang/test/Frontend/unknown-arg.c9
6 files changed, 67 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 45cdf82d369..217aea22b71 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -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">,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 325b233ac5e..a5aed299e39 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -188,9 +188,19 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
// 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(ArrayRef<const char *> ArgStrings,
}
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;
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 6ce719aac67..ce875fa03b9 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2757,7 +2757,13 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
// 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;
}
diff --git a/clang/test/Driver/unknown-arg.c b/clang/test/Driver/unknown-arg.c
index 9bba74a942e..aebf84c561f 100644
--- a/clang/test/Driver/unknown-arg.c
+++ b/clang/test/Driver/unknown-arg.c
@@ -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:
diff --git a/clang/test/Driver/unsupported-option.c b/clang/test/Driver/unsupported-option.c
new file mode 100644
index 00000000000..39f135e6834
--- /dev/null
+++ b/clang/test/Driver/unsupported-option.c
@@ -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'?
diff --git a/clang/test/Frontend/unknown-arg.c b/clang/test/Frontend/unknown-arg.c
new file mode 100644
index 00000000000..00f2da6242c
--- /dev/null
+++ b/clang/test/Frontend/unknown-arg.c
@@ -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'?
OpenPOWER on IntegriCloud