int NumArgs = 0;
string HelpText = ?;
string MetaVarName = ?;
+ string Values = ?;
list<OptionFlag> Flags = [];
OptionGroup Group = ?;
Option Alias = ?;
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.
unsigned short GroupID;
unsigned short AliasID;
const char *AliasArgs;
+ const char *Values;
};
private:
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
UnknownClass,
FlagClass,
JoinedClass,
+ ValuesClass,
SeparateClass,
RemainingArgsClass,
RemainingArgsJoinedClass,
case CommaJoinedClass:
return RenderCommaJoinedStyle;
case FlagClass:
+ case ValuesClass:
case SeparateClass:
case MultiArgClass:
case JoinedOrSeparateClass:
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)) {
case Option::FlagClass:
break;
+ case Option::ValuesClass:
+ break;
+
case Option::SeparateClass: case Option::JoinedOrSeparateClass:
case Option::RemainingArgsClass: case Option::RemainingArgsJoinedClass:
Name += ' ';
P(UnknownClass);
P(FlagClass);
P(JoinedClass);
+ P(ValuesClass);
P(SeparateClass);
P(CommaJoinedClass);
P(MultiArgClass);
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
};
#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
};
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
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
};
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
};
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
};
OS << ", nullptr";
// The option meta-variable name (unused).
+ OS << ", nullptr";
+
+ // The option Values (unused for groups).
OS << ", nullptr)\n";
}
OS << "\n";
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";