Skip to content

Instantly share code, notes, and snippets.

@yamaguchi1024
Created May 16, 2017 13:21
Show Gist options
  • Save yamaguchi1024/0f312462d78cd3df256cb553bf2752e3 to your computer and use it in GitHub Desktop.
Save yamaguchi1024/0f312462d78cd3df256cb553bf2752e3 to your computer and use it in GitHub Desktop.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d812bd8..4f1ea08 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -469,6 +469,7 @@ def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">;
def arch : Separate<["-"], "arch">, Flags<[DriverOption]>;
def arch__only : Separate<["-"], "arch_only">;
def a : Joined<["-"], "a">;
+def autocomplete : Joined<["--"], "autocomplete=">;
def bind__at__load : Flag<["-"], "bind_at_load">;
def bundle__loader : Separate<["-"], "bundle_loader">;
def bundle : Flag<["-"], "bundle">;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f36deff..bec4bf4 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1216,6 +1216,13 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
return false;
}
+ if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {
+ // Print out all options that start with a given argument. This is used for
+ // shell autocompletion.
+ llvm::outs() << llvm::join(Opts->findByPrefix(A->getValue()), " ") << '\n';
+ return false;
+ }
+
if (C.getArgs().hasArg(options::OPT_print_libgcc_file_name)) {
ToolChain::RuntimeLibType RLT = TC.GetRuntimeLibType(C.getArgs());
switch (RLT) {
diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c
new file mode 100644
index 0000000..dab6455
--- /dev/null
+++ b/clang/test/Driver/autocomplete.c
@@ -0,0 +1,3 @@
+// RUN: %clang --autocomplete=-fsyn | grep '\-fsyntax-only'
+// RUN: %clang --autocomplete=-s | grep '\-std=.*-stdlib='
+// RUN: %clang --autocomplete=foo | grep -v .
diff --git a/clang/utils/bash-autocomplete.sh b/clang/utils/bash-autocomplete.sh
new file mode 100644
index 0000000..f01089f
--- /dev/null
+++ b/clang/utils/bash-autocomplete.sh
@@ -0,0 +1,14 @@
+_clang()
+{
+ local cur prev words cword flags
+ _init_completion -n : || return
+
+ flags=$( clang --autocomplete="$cur" )
+ if [[ "$flags" == "" || "$cur" == "" ]]; then
+ _filedir
+ else
+ COMPREPLY=( $( compgen -W "$flags" -- "$cur") )
+ fi
+
+} &&
+ complete -F _clang clang
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 390e527..ebf78db 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -113,6 +113,14 @@ public:
return getInfo(id).MetaVar;
}
+ /// \brief Find flags from OptTable which starts with Cur.
+ /// This is used for shell autocompletion.
+ ///
+ /// \param [in] Cur - String of user input.
+ ///
+ /// \return The vector of flags which starts with Cur.
+ std::vector<std::string> findByPrefix(StringRef Cur) const;
+
/// \brief Parse a single argument; returning the new argument and
/// updating Index.
///
diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp
index 7eafb00..b09f8d3 100644
--- a/llvm/lib/Option/OptTable.cpp
+++ b/llvm/lib/Option/OptTable.cpp
@@ -186,6 +186,20 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,
return 0;
}
+std::vector<std::string> OptTable::findByPrefix(StringRef Cur) const {
+ std::vector<std::string> Ret;
+ for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) {
+ if (!In.Prefixes)
+ continue;
+ for (int I = 0; In.Prefixes[I]; I++) {
+ std::string S = (std::string(In.Prefixes[I]) + std::string(In.Name));
+ if (StringRef(S).startswith(Cur))
+ Ret.push_back(S);
+ }
+ }
+ return Ret;
+}
+
Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index,
unsigned FlagsToInclude,
unsigned FlagsToExclude) const {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment