diff options
| author | Yuka Takahashi <yukatkh@gmail.com> | 2018-03-05 08:54:20 +0000 | 
|---|---|---|
| committer | Yuka Takahashi <yukatkh@gmail.com> | 2018-03-05 08:54:20 +0000 | 
| commit | 41789e46a66d22f89fb2a3f38fd7be2b4586f7fd (patch) | |
| tree | e1eb0d0f86ab2b6bc47ac5fd5eb5dee562478493 /clang/lib | |
| parent | 34be1b0288bb9b383e86a28bbd4e2cc6512d7662 (diff) | |
| download | bcm5719-llvm-41789e46a66d22f89fb2a3f38fd7be2b4586f7fd.tar.gz bcm5719-llvm-41789e46a66d22f89fb2a3f38fd7be2b4586f7fd.zip | |
[Bash-autocompletion] Pass all flags in shell command-line to Clang
Previously, we passed "#" to --autocomplete to indicate to enable cc1
flags. For example, when -cc1 or -Xclang was passed to bash, bash
executed `clang --autocomplete=#-<flag they want to complete>`.
However, this was not a good implementation because it depends -Xclang
and -cc1 parsing to shell. So I changed this to pass all flags shell
has, so that Clang can handle them internally.
I had to change many testcases because API spec changed quite a lot.
Reviewers: teemperor, v.g.vassilev
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D39342
llvm-svn: 326684
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Driver/Driver.cpp | 50 | 
1 files changed, 31 insertions, 19 deletions
| diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 88412e35958..b0a64354f8d 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1419,44 +1419,56 @@ static void PrintDiagnosticCategories(raw_ostream &OS) {      OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n';  } -void Driver::handleAutocompletions(StringRef PassedFlags) const { +void Driver::HandleAutocompletions(StringRef PassedFlags) const { +  if (PassedFlags == "") return;    // Print out all options that start with a given argument. This is used for    // shell autocompletion.    std::vector<std::string> SuggestedCompletions; +  std::vector<std::string> Flags;    unsigned short DisableFlags =        options::NoDriverOption | options::Unsupported | options::Ignored; -  // We want to show cc1-only options only when clang is invoked as "clang -  // -cc1". When clang is invoked as "clang -cc1", we add "#" to the beginning -  // of an --autocomplete  option so that the clang driver can distinguish -  // whether it is requested to show cc1-only options or not. -  if (PassedFlags.size() > 0 && PassedFlags[0] == '#') { + +  // Parse PassedFlags by "," as all the command-line flags are passed to this +  // function separated by "," +  StringRef TargetFlags = PassedFlags; +  while (TargetFlags != "") { +    StringRef CurFlag; +    std::tie(CurFlag, TargetFlags) = TargetFlags.split(","); +    Flags.push_back(std::string(CurFlag)); +  } + +  // We want to show cc1-only options only when clang is invoked with -cc1 or +  // -Xclang. +  if (std::find(Flags.begin(), Flags.end(), "-Xclang") != Flags.end() || std::find(Flags.begin(), Flags.end(), "-cc1") != Flags.end())      DisableFlags &= ~options::NoDriverOption; -    PassedFlags = PassedFlags.substr(1); + +  StringRef Cur; +  Cur = Flags.at(Flags.size() - 1); +  StringRef Prev; +  if (Flags.size() >= 2) { +    Prev = Flags.at(Flags.size() - 2); +    SuggestedCompletions = Opts->suggestValueCompletions(Prev, Cur);    } -  if (PassedFlags.find(',') == StringRef::npos) { +  if (SuggestedCompletions.empty()) +    SuggestedCompletions = Opts->suggestValueCompletions(Cur, ""); + +  if (SuggestedCompletions.empty()) {      // If the flag is in the form of "--autocomplete=-foo",      // we were requested to print out all option names that start with "-foo".      // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". -    SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags); +    SuggestedCompletions = Opts->findByPrefix(Cur, DisableFlags);      // We have to query the -W flags manually as they're not in the OptTable.      // TODO: Find a good way to add them to OptTable instead and them remove      // this code.      for (StringRef S : DiagnosticIDs::getDiagnosticFlags()) -      if (S.startswith(PassedFlags)) +      if (S.startswith(Cur))          SuggestedCompletions.push_back(S); -  } else { -    // If the flag is in the form of "--autocomplete=foo,bar", we were -    // requested to print out all option values for "-foo" that start with -    // "bar". For example, -    // "--autocomplete=-stdlib=,l" is expanded to "libc++" and "libstdc++". -    StringRef Option, Arg; -    std::tie(Option, Arg) = PassedFlags.split(','); -    SuggestedCompletions = Opts->suggestValueCompletions(Option, Arg);    } +    // Sort the autocomplete candidates so that shells print them out in a    // deterministic order. We could sort in any way, but we chose    // case-insensitive sorting for consistency with the -help option @@ -1574,7 +1586,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {    if (Arg *A = C.getArgs().getLastArg(options::OPT_autocomplete)) {      StringRef PassedFlags = A->getValue(); -    handleAutocompletions(PassedFlags); +    HandleAutocompletions(PassedFlags);      return false;    } | 

