[cfe-dev] Using isa & co with custom class hierarchy

Sebastian Redl sebastian.redl at getdesigned.at
Wed Aug 25 11:48:14 PDT 2010


On Aug 25, 2010, at 11:22 AM, Jan Bierbaum wrote:

> Hi Victor!
> 
> 
> Thanks for your answer.
> 
> Victor Zverovich meinte am 25.08.2010 18:33:
>> The problem is that B::classof(const A *) always return true in your
>> implementation, so llvm::isa<B>(a)returns true as well.
> 
> Yeah, but that one is intended. Every instance of B "is a" instance of A
> due to inheritance. I just modeled this in the 'classof' method.

Here's how isa is implemented (leaving aside all the unwrapping magic):

template <typename Test, typename Arg>
bool isa(Arg *Ptr) {
  return Test::classof(Ptr);
}

For a class Class, Class::classof is supposed to check if Class is the dynamic type (or a superclass thereof) of the argument.

So A::classof(A*) tests whether A is a valid cast target for the given object, which is trivially true.
B::classof(A*) tests whether B is a valid cast target for the given object. This is NOT trivially true, since it's only true for objects whose dynamic type is actually B, but the A* could point to an A. This is where the real work needs to be done. However, you return true here, which is why isa<B>(a) returns true. Remember, isa<B>(a) == B::classof(a) == true in your implementation.
B::classof(B*), finally, is simply an optimization. When the type of the object is statically known to be at least a B, there's no need to perform a runtime check.

> Then for example
> 'CXXRecordDecl' [2] define the following (besides others):

Those others are what's important. In particular, look at the overload that takes a Decl*.
In fact I think that the ClassTemplateSpecializationDecl overload here is completely superfluous. I have no idea why it's there.

> So 'isa<A>(b)' should report false/0.


A::classof(b) -> A::classof(A*) (since there's no B* overload) -> true.

You don't have any classof function that can return false, ever. Therefore, all isa tests will always return true. (A missing classof is a compile error, not a result of false.)

Sebastian



More information about the cfe-dev mailing list