Skip to content

Instantly share code, notes, and snippets.

@yamaguchi1024
Last active May 21, 2017 07:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yamaguchi1024/3813d122e9e2af64ffd105b45eed686b to your computer and use it in GitHub Desktop.
Save yamaguchi1024/3813d122e9e2af64ffd105b45eed686b to your computer and use it in GitHub Desktop.
diff --git a/clang/include/clang/Driver/Options.h b/clang/include/clang/Driver/Options.h
index 57e4452..382e618 100644
--- a/clang/include/clang/Driver/Options.h
+++ b/clang/include/clang/Driver/Options.h
@@ -40,7 +40,7 @@ enum ClangFlags {
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, VALUE) OPT_##ID,
#include "clang/Driver/Options.inc"
LastOption
#undef OPTION
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 4f1ea08..0dc873d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2195,7 +2195,7 @@ def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
Group<CompileOnly_Group>, HelpText<"Language standard to compile for">;
def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
- HelpText<"C++ standard library to use">;
+ HelpText<"C++ standard library to use">, Value<"libc++,libstdc++,platform">;
def sub__library : JoinedOrSeparate<["-"], "sub_library">;
def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
def system_header_prefix : Joined<["--"], "system-header-prefix=">,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index bec4bf4..05b47dc 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1219,7 +1219,13 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
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';
+ StringRef S = A->getValue();
+ SmallVector<StringRef, 8> Split;
+ S.split(Split, ",", -1, false);
+ std::vector<std::string> V = Opts->findByPrefix(Split[0]);
+ if (V.empty())
+ V = Opts->findByValue(Split);
+ llvm::outs() << llvm::join(V, " ") << '\n';
return false;
}
diff --git a/clang/lib/Driver/DriverOptions.cpp b/clang/lib/Driver/DriverOptions.cpp
index 6a74109..aae7660 100644
--- a/clang/lib/Driver/DriverOptions.cpp
+++ b/clang/lib/Driver/DriverOptions.cpp
@@ -22,9 +22,9 @@ using namespace llvm::opt;
static const OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
+ HELPTEXT, METAVAR, VALUE) \
{ PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
- FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
+ FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUE },
#include "clang/Driver/Options.inc"
#undef OPTION
};
diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c
index 94649f2..96e539e 100644
--- a/clang/test/Driver/autocomplete.c
+++ b/clang/test/Driver/autocomplete.c
@@ -4,3 +4,5 @@
// STD: -std={{.*}}-stdlib=
// RUN: %clang --autocomplete=foo | not FileCheck %s -check-prefix=NONE
// NONE: foo
+// RUN: %clang --autocomplete=l,=,-stdlib | FileCheck %s -check-prefix=STDLIB
+// STDLIB: libc++ libstdc++
diff --git a/clang/utils/bash-autocomplete.sh b/clang/utils/bash-autocomplete.sh
index a906712..3bf3730 100644
--- a/clang/utils/bash-autocomplete.sh
+++ b/clang/utils/bash-autocomplete.sh
@@ -4,11 +4,17 @@ _clang()
local cur prev words cword flags
_init_completion -n : || return
- flags=$( clang --autocomplete="$cur" )
+ arg=""
+ for (( i = $cword; i >= 1; i-- )) ;
+ do
+ arg="$arg""${COMP_WORDS[$i]},"
+ done
+
+ flags=$( clang --autocomplete="$arg" )
if [[ "$flags" == "" || "$cur" == "" ]]; then
_filedir
else
COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) )
fi
-}
+}
complete -F _clang clang
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index ad72562..407d462 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -185,7 +185,7 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
// Create enum with OPT_xxx values for each option in Options.td
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
};
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 252590c..83bcb29 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -659,10 +659,10 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
// Create table mapping all options defined in Options.td
static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
+#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 \
+ OPT_##GROUP, OPT_##ALIAS, X6, X11 \
},
#include "Options.inc"
#undef OPTION
diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index af88341..076dda7 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -58,7 +58,7 @@ public:
// Create enum with OPT_xxx values for each option in Options.td
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
};
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index f4eadee..9a38c78 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -42,9 +42,9 @@ using namespace lld::elf;
// Create table mapping all options defined in Options.td
static const opt::OptTable::Info OptInfo[] = {
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
+#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10, X11) \
{X1, X2, X9, X10, OPT_##ID, opt::Option::KIND##Class, \
- X8, X7, OPT_##GROUP, OPT_##ALIAS, X6},
+ X8, X7, OPT_##GROUP, OPT_##ALIAS, X6, X11},
#include "Options.inc"
#undef OPTION
};
diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp
index 9b4aede..eb1e178 100644
--- a/lld/lib/Driver/DarwinLdDriver.cpp
+++ b/lld/lib/Driver/DarwinLdDriver.cpp
@@ -62,7 +62,7 @@ namespace {
enum {
OPT_INVALID = 0,
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
+ HELP, META, VALUE) \
OPT_##ID,
#include "DarwinLdOptions.inc"
#undef OPTION
@@ -76,9 +76,9 @@ enum {
// Create table mapping all options defined in DarwinLdOptions.td
static const llvm::opt::OptTable::Info infoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
+ HELPTEXT, METAVAR, VALUE) \
{ PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
+ PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUE },
#include "DarwinLdOptions.inc"
#undef OPTION
};
diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td
index 4da86f0..815474d 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -92,6 +92,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
int NumArgs = 0;
string HelpText = ?;
string MetaVarName = ?;
+ string Value = ?;
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 Value<string value> { string Value = value; }
// Predefined options.
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index 8a323a2..48437cb 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -46,6 +46,7 @@ public:
unsigned short GroupID;
unsigned short AliasID;
const char *AliasArgs;
+ const char *Value;
};
private:
@@ -113,6 +114,7 @@ public:
return getInfo(id).MetaVar;
}
+ std::vector<std::string> findByValue(const SmallVectorImpl<StringRef> &Command) const;
/// Find flags from OptTable which starts with Cur.
///
/// \param [in] Cur - String prefix that all returned flags need
diff --git a/llvm/include/llvm/Option/Option.h b/llvm/include/llvm/Option/Option.h
index 139f281..f6df35f 100644
--- a/llvm/include/llvm/Option/Option.h
+++ b/llvm/include/llvm/Option/Option.h
@@ -49,6 +49,7 @@ public:
UnknownClass,
FlagClass,
JoinedClass,
+ ValueClass,
SeparateClass,
RemainingArgsClass,
RemainingArgsJoinedClass,
@@ -147,6 +148,7 @@ public:
case CommaJoinedClass:
return RenderCommaJoinedStyle;
case FlagClass:
+ case ValueClass:
case SeparateClass:
case MultiArgClass:
case JoinedOrSeparateClass:
diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp
index b00d21e..a89a2e0 100644
--- a/llvm/lib/Option/OptTable.cpp
+++ b/llvm/lib/Option/OptTable.cpp
@@ -186,6 +186,30 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,
return 0;
}
+std::vector<std::string>
+OptTable::findByValue(const SmallVectorImpl<StringRef> &Command) const {
+ if (Command.size() <= 1)
+ return {};
+
+ std::vector<std::string> Ret;
+ for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) {
+ if (!In.Value)
+ continue;
+ std::string S = "-" + std::string(In.Name);
+ std::string C = (Command[1] == "=") ?
+ std::string(Command[2]) + "=" : std::string(Command[1]);
+ if (S != C)
+ continue;
+
+ SmallVector<StringRef, 8> Values;
+ StringRef(In.Value).split(Values, ",", -1, false);
+ for (StringRef Val : Values)
+ if (Val.startswith(Command[0]))
+ Ret.push_back(Val);
+ }
+ return Ret;
+}
+
std::vector<std::string> OptTable::findByPrefix(StringRef Cur) const {
std::vector<std::string> Ret;
for (const Info &In : OptionInfos.slice(FirstSearchableIndex)) {
@@ -328,6 +352,9 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
case Option::FlagClass:
break;
+ case Option::ValueClass:
+ break;
+
case Option::SeparateClass: case Option::JoinedOrSeparateClass:
case Option::RemainingArgsClass: case Option::RemainingArgsJoinedClass:
Name += ' ';
diff --git a/llvm/lib/Option/Option.cpp b/llvm/lib/Option/Option.cpp
index 736b939..22b8f0e 100644
--- a/llvm/lib/Option/Option.cpp
+++ b/llvm/lib/Option/Option.cpp
@@ -45,6 +45,7 @@ void Option::print(raw_ostream &O) const {
P(UnknownClass);
P(FlagClass);
P(JoinedClass);
+ P(ValueClass);
P(SeparateClass);
P(CommaJoinedClass);
P(MultiArgClass);
diff --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 3bae382..58298ba 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -30,7 +30,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
};
@@ -40,10 +40,10 @@ enum {
#undef PREFIX
static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
+#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 \
+ OPT_##GROUP, OPT_##ALIAS, X6, X11 \
},
#include "Options.inc"
#undef OPTION
diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
index f03e0b7..d711044 100644
--- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
+++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp
@@ -31,7 +31,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, VALUE) \
OPT_##ID,
#include "Opts.inc"
#undef OPTION
@@ -43,12 +43,12 @@ enum ID {
static const opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
+ HELPTEXT, METAVAR, VALUE) \
{ \
PREFIX, NAME, HELPTEXT, \
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
PARAM, FLAGS, OPT_##GROUP, \
- OPT_##ALIAS, ALIASARGS},
+ OPT_##ALIAS, ALIASARGS, VALUE },
#include "Opts.inc"
#undef OPTION
};
diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp
index 8630ff1..ede5127 100644
--- a/llvm/unittests/Option/OptionParsingTest.cpp
+++ b/llvm/unittests/Option/OptionParsingTest.cpp
@@ -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, VALUE) \
+ 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) \
+ HELPTEXT, METAVAR, VALUE) \
{ PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
- FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
+ FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUE },
#include "Opts.inc"
#undef OPTION
};
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index c1b5e65..5e16ef2 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -194,6 +194,8 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << ", nullptr";
// The option meta-variable name (unused).
+ OS << ", nullptr";
+
OS << ", nullptr)\n";
}
OS << "\n";
@@ -283,6 +285,12 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
else
OS << "nullptr";
+ OS << ", ";
+ if (!isa<UnsetInit>(R.getValueInit("Value")))
+ write_cstring(OS, R.getValueAsString("Value"));
+ else
+ OS << "nullptr";
+
OS << ")\n";
}
OS << "#endif // OPTION\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment