mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +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:
parent
f4fed2c4b8
commit
3b19a660ec
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 += ' ';
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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},
|
||||
OPT_##ALIAS, ALIASARGS, VALUES},
|
||||
#include "Opts.inc"
|
||||
#undef OPTION
|
||||
};
|
||||
|
@ -19,7 +19,8 @@ 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,
|
||||
HELPTEXT, METAVAR, VALUES) \
|
||||
OPT_##ID,
|
||||
#include "Opts.inc"
|
||||
LastOption
|
||||
#undef OPTION
|
||||
@ -37,9 +38,9 @@ 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 },
|
||||
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
|
||||
};
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user