Tweak the way that is_a is implemented
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.