llvm🆑:parser subclasses final in 3.7?


I’m upgrading some code that uses LLVM from 3.6 to 3.7. It looks like the llvm::cl::parser subclasses are now final?

We had been doing:

struct MaxThreadsParser : public llvm::cl::parser {
bool parse(llvm::cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg,
unsigned &Val);

But that’s now causing:

In file included from /home/lak/my_svn/llvm-carte/llvm-3.7.0/tools/carte++/tools/ir2v/ThreadSupport.cpp:1:
/home/lak/my_svn/llvm-carte/llvm-3.7.0/tools/carte++/tools/ir2v/ThreadSupport.h:12:34: error:
base ‘parser’ is marked ‘final’
struct MaxThreadsParser : public llvm::cl::parser {

What’s the new way to do this now? It looks like the documentation at http://llvm.org/releases/3.7.0/docs/CommandLine.html#custom-parsers describes a way that doesn’t work anymore.



Yeah, someone filed https://llvm.org/bugs/show_bug.cgi?id=25104 for this

I was the person who made this API change - hadn't seen the documentation
we had suggesting/encouraging people to do this, but I'm sort of inclined
to say that was a mistake - but open to discussion.

The reason for the change was to devirtualize parser<T>'s dtor - since it
wasn't ever owned/destroyed polymorphically, so there was no need for it.
But to keep the type safe, this meant making the dtor protected in the base
class and making the derived classes final (so there couldn't be further
derived classes and then polymorphic ownership of the intermediate class

Not sure how other people feel about it - whether this is a particularly
compelling extension point for us to support.

It looks like you could just write your class as a subclass of
basic_parser<unsigned> and go from there instead of deriving from parser<T>
directly. You might have to implement one or two more functions that way.

- David

It ended up being fairly simple to subclass basic_parser<unsigned>, though
it did require a non-obvious (to me), explicit template specialization of
llvm::cl::printOptionDiff. I liked the simplicity of the being able to
subclass parser<T> and define a single method, but it really doesn't matter
that much.

Thanks for the information and for pointing me in the right direction.