1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[GSoC] Flag value completion for clang

This is patch for GSoC project, bash-completion for clang.

To use this on bash, please run `source clang/utils/bash-autocomplete.sh`.
bash-autocomplete.sh is code for bash-completion.

In this patch, Options.td was mainly changed in order to add value class
in Options.inc.

llvm-svn: 305805
This commit is contained in:
Yuka Takahashi 2017-06-20 16:31:31 +00:00
parent f4fed2c4b8
commit 3b19a660ec
9 changed files with 80 additions and 18 deletions

View File

@ -92,6 +92,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
int NumArgs = 0;
string HelpText = ?;
string MetaVarName = ?;
string Values = ?;
list<OptionFlag> Flags = [];
OptionGroup Group = ?;
Option Alias = ?;
@ -126,6 +127,7 @@ class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
class Group<OptionGroup group> { OptionGroup Group = group; }
class HelpText<string text> { string HelpText = text; }
class MetaVarName<string name> { string MetaVarName = name; }
class Values<string value> { string Values = value; }
// Predefined options.

View File

@ -53,6 +53,7 @@ public:
unsigned short GroupID;
unsigned short AliasID;
const char *AliasArgs;
const char *Values;
};
private:
@ -120,6 +121,19 @@ public:
return getInfo(id).MetaVar;
}
/// Find possible value for given flags. This is used for shell
/// autocompletion.
///
/// \param [in] Option - Key flag like "-stdlib=" when "-stdlib=l"
/// was passed to clang.
///
/// \param [in] Arg - Value which we want to autocomplete like "l"
/// when "-stdlib=l" was passed to clang.
///
/// \return The vector of possible values.
std::vector<std::string> suggestValueCompletions(StringRef Option,
StringRef Arg) const;
/// Find flags from OptTable which starts with Cur.
///
/// \param [in] Cur - String prefix that all returned flags need

View File

@ -57,6 +57,7 @@ public:
UnknownClass,
FlagClass,
JoinedClass,
ValuesClass,
SeparateClass,
RemainingArgsClass,
RemainingArgsJoinedClass,
@ -155,6 +156,7 @@ public:
case CommaJoinedClass:
return RenderCommaJoinedStyle;
case FlagClass:
case ValuesClass:
case SeparateClass:
case MultiArgClass:
case JoinedOrSeparateClass:

View File

@ -194,6 +194,37 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,
return 0;
}
// Returns true if one of the Prefixes + In.Names matches Option
static bool optionMatches(const OptTable::Info &In, StringRef Option) {
if (In.Values && In.Prefixes)
for (size_t I = 0; In.Prefixes[I]; I++)
if (Option == std::string(In.Prefixes[I]) + In.Name)
return true;
return false;
}
// This function is for flag value completion.
// Eg. When "-stdlib=" and "l" was passed to this function, it will return
// appropiriate values for stdlib, which starts with l.
std::vector<std::string>
OptTable::suggestValueCompletions(StringRef Option, StringRef Arg) const {
// Search all options and return possible values.
for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) {
if (!optionMatches(In, Option))
continue;
SmallVector<StringRef, 8> Candidates;
StringRef(In.Values).split(Candidates, ",", -1, false);
std::vector<std::string> Result;
for (StringRef Val : Candidates)
if (Val.startswith(Arg))
Result.push_back(Val);
return Result;
}
return {};
}
std::vector<std::string> OptTable::findByPrefix(StringRef Cur) const {
std::vector<std::string> Ret;
for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) {
@ -336,6 +367,9 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
case Option::FlagClass:
break;
case Option::ValuesClass:
break;
case Option::SeparateClass: case Option::JoinedOrSeparateClass:
case Option::RemainingArgsClass: case Option::RemainingArgsJoinedClass:
Name += ' ';

View File

@ -47,6 +47,7 @@ void Option::print(raw_ostream &O) const {
P(UnknownClass);
P(FlagClass);
P(JoinedClass);
P(ValuesClass);
P(SeparateClass);
P(CommaJoinedClass);
P(MultiArgClass);

View File

@ -31,7 +31,7 @@ namespace {
enum {
OPT_INVALID = 0,
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};
@ -41,11 +41,9 @@ enum {
#undef PREFIX
static const llvm::opt::OptTable::Info infoTable[] = {
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
{ \
X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
OPT_##GROUP, OPT_##ALIAS, X6 \
},
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10, X11) \
{X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, \
X8, X7, OPT_##GROUP, OPT_##ALIAS, X6, X11},
#include "Options.inc"
#undef OPTION
};

View File

@ -37,7 +37,7 @@ namespace {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR) \
HELPTEXT, METAVAR, VALUES) \
OPT_##ID,
#include "Opts.inc"
#undef OPTION
@ -49,12 +49,12 @@ enum ID {
static const opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR) \
HELPTEXT, METAVAR, VALUES) \
{ \
PREFIX, NAME, HELPTEXT, \
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
PARAM, FLAGS, OPT_##GROUP, \
OPT_##ALIAS, ALIASARGS},
PREFIX, NAME, HELPTEXT, \
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
PARAM, FLAGS, OPT_##GROUP, \
OPT_##ALIAS, ALIASARGS, VALUES},
#include "Opts.inc"
#undef OPTION
};

View File

@ -18,8 +18,9 @@ using namespace llvm::opt;
enum ID {
OPT_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
OPT_##ID,
#include "Opts.inc"
LastOption
#undef OPTION
@ -36,10 +37,10 @@ enum OptionFlags {
};
static const OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR) \
{ PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
{PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \
PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUES},
#include "Opts.inc"
#undef OPTION
};

View File

@ -196,6 +196,9 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << ", nullptr";
// The option meta-variable name (unused).
OS << ", nullptr";
// The option Values (unused for groups).
OS << ", nullptr)\n";
}
OS << "\n";
@ -285,6 +288,13 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
else
OS << "nullptr";
// The option Values. Used for shell autocompletion.
OS << ", ";
if (!isa<UnsetInit>(R.getValueInit("Values")))
write_cstring(OS, R.getValueAsString("Values"));
else
OS << "nullptr";
OS << ")\n";
}
OS << "#endif // OPTION\n";