Index: include/llvm/Support/CommandLine.h =================================================================== --- include/llvm/Support/CommandLine.h +++ include/llvm/Support/CommandLine.h @@ -570,21 +570,28 @@ // the overhead is less, and most importantly, it keeps them in the order // inserted so we can print our option out nicely. SmallVector>, 4> Values; - void processValues(va_list Vals); + + template + void processArgs(const char *Name, int Val, const char *Desc, Remaining... Args) { + auto EnumVal = static_cast(Val); + Values.push_back(std::make_pair(StringRef(Name), + std::make_pair(EnumVal, StringRef(Desc)))); + processArgs(Args...); + } + + template void processArgs(SentinalT) { + // FIXME: Remove sentinal argument at all of the call sites. + static_assert(std::is_same::value, + "incorrect sentinal type"); + } public: + template ValuesClass(StringRef EnumName, DataType Val, StringRef Desc, - va_list ValueArgs) { + Args... ValueArgs) { // Insert the first value, which is required. Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc))); - - // Process the varargs portion of the values... - while (const char *enumName = va_arg(ValueArgs, const char * )) { - DataType EnumVal = static_cast(va_arg(ValueArgs, int)); - auto EnumDesc = StringRef(va_arg(ValueArgs, const char * )); - Values.push_back(std::make_pair(StringRef(enumName), // Add value to value map - std::make_pair(EnumVal, EnumDesc))); - } + processArgs(ValueArgs...); } template void apply(Opt &O) const { @@ -594,13 +601,10 @@ } }; -template -ValuesClass LLVM_END_WITH_NULL -values(StringRef Arg, DataType Val, StringRef Desc, ...) { - va_list ValueArgs; - va_start(ValueArgs, Desc); - ValuesClass Vals(Arg, Val, Desc, ValueArgs); - va_end(ValueArgs); +template +ValuesClass values(StringRef Arg, DataType Val, StringRef Desc, + Args &&... ValueArgs) { + ValuesClass Vals(Arg, Val, Desc, std::forward(ValueArgs)...); return Vals; }