On 11/13/20 1:16 AM, Richard Sandiford via Gcc-patches wrote:
> At the moment, class hierarchies that use is_a are expected
> to define specialisations like:
>
> template <>
> template <>
> inline bool
> is_a_helper <cgraph_node *>::test (symtab_node *p)
> {
> return p->type == SYMTAB_FUNCTION;
> }
>
> But this doesn't scale well to larger hierarchies, because it only
> defines ::test for an argument that is exactly “symtab_node *”
> (and not for example “const symtab_node *” or something that
> comes between cgraph_node and symtab_node in the hierarchy).
>
> For example:
>
> struct A { int x; };
> struct B : A {};
> struct C : B {};
>
> template <>
> template <>
> inline bool
> is_a_helper <C *>::test (A *a)
> {
> return a->x == 1;
> }
>
> bool f(B *b) { return is_a<C *> (b); }
>
> gives:
>
> warning: inline function ‘static bool is_a_helper<T>::test(U*) [with U = B;
> T = C*]’ used but never defined
>
> and:
>
> bool f(const A *a) { return is_a<const C *> (a); }
>
> gives:
>
> warning: inline function ‘static bool is_a_helper<T>::test(U*) [with U =
> const A; T = const C*]’ used but never defined
>
> This patch instead allows is_a to be implemented by specialising
> is_a_helper as a whole, for example:
>
> template<>
> struct is_a_helper<C *> : static_is_a_helper<C *>
> {
> static inline bool test (const A *a) { return a->x == 1; }
> };
>
> It also adds a general specialisation of is_a_helper for const
> pointers. Together, this makes both of the above examples work.
>
> gcc/
> * is-a.h (reinterpret_is_a_helper): New class.
> (static_is_a_helper): Likewise.
> (is_a_helper): Inherit from reinterpret_is_a_helper.
> (is_a_helper<const T *>): New specialization.
OK
Jeff