Variadic templates for llvm::opt::ArgList/llvm::opt::option::matches

I’m curious: did anybody ever consider using variadic templates for the highly redundant overloads in ArgList.cpp? It’s a very textbook use-case.

“Templates are confusing to many programmers” is a perfectly valid answer.

Code like seven of these:

Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
OptSpecifier Id2, OptSpecifier Id3,
OptSpecifier Id4, OptSpecifier Id5,
OptSpecifier Id6, OptSpecifier Id7) const;

…could be replaced by code that looks something like this:

//In llvm/Option/Option.h
template

bool Option::matches(T Opt0) const {

return Option::matches(Opt0);
}

template<typename T, typename… Opts>

bool Option::matches(T Opt0, Opts… opts) const {

return Option::matches(Opt0) || matches(opts…);

}

//In llvm/Option/ArgList.cpp
template<typename… Ids>

Arg *ArgList::getLastArg(Ids… ids) const {

[…loop here…]
if((*it)->getOption().matches(ids…))
Res = *it;
Res->claim();
[etc…]

Much of this sort of thing is legacy code from before C++11 existed/before LLVM adopted C++11.

I think “patches welcome” is correct here - we have converted some things to variadic templates (usually if someone wanted one more overload - just fix it by switching to a variadic template instead), but no global cleanup has been done (nor expected - but appreciated if anyone feels like doing so :))

  • Dave