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

Reply via email to