[cfe-dev] isDerivedFrom() on template classes

Sebastian Redl sebastian.redl at getdesigned.at
Mon Sep 5 09:44:37 PDT 2011


On 05.09.2011 16:32, Benjamin Orgogozo wrote:
> Hello,
>
> I'm trying to write a clang plugin which must check if a particular
> class derives from a class A.
>
> I have a problem when the B class looks like:
>
> template<class U>
> class B : public A<  B<U>  >  {
> };
>
>
>
> So I don't detect that B inherits from A.
>
> Do you know if there is a way to do detect that B inherits from A in
> that case?
Tricky. First, B is not a class, it's a class template. So you can 
easily detect whether any given instantiation derives from some 
instantiation of A, but in general, the question is not as easy to 
answer. What would isDerivedFrom() tell you about B if there was a 
specialization of B thus:

template <>
class B<int> { // int is easy, not worth deriving from A
};

That's the main problem with saying anything about templates: for any 
given set of arguments, the situation might be completely different.

That said, we have some heuristics in the error recovery for accessing 
members of dependent bases from a template. That is, take this code:

template <typename T>
struct A {
   int i;
};
template <typename T>
struct B : A<T> {
   void f() { i = 0; }
};
void g() {
   B<int> b; b.f();
}

Check out the error message you get. There should be a note saying that 
it can find an 'i' in A, but you have to use this->i to access it. 
Follow the code to where it generates this diagnostic, and you can find 
the heuristics that look into dependent bases.

Or, alternatively, just walk the base specifiers of the primary template 
definition and look for instantiations of whatever template you're 
looking for.

Sebastian



More information about the cfe-dev mailing list