======================================================
How to set up LLVM-style RTTI for your class hierarchy
======================================================

.. contents::

Background
==========

LLVM avoids using C++'s built in RTTI. Instead, it  pervasively uses its
own hand-rolled form of RTTI which is much more efficient and flexible,
although it requires a bit more work from you as a class author.

A description of how to use LLVM-style RTTI from a client's perspective is
given in the `Programmer's Manual <ProgrammersManual.html#isa>`_. This
document, in contrast, discusses the steps you need to take as a class
hierarchy author to make LLVM-style RTTI available to your clients.

Before diving in, make sure that you are familiar with the Object Oriented
Programming concept of "`is-a`_".

.. _is-a: http://en.wikipedia.org/wiki/Is-a

Basic Setup
===========

This section describes how to set up the most basic form of LLVM-style RTTI
(which is sufficient for 99.9% of the cases). We will set up LLVM-style
RTTI for this class hierarchy:

.. code-block:: c++

   class Shape {
   public:
     Shape() {}
     virtual double computeArea() = 0;
   };

   class Square : public Shape {
     double SideLength;
   public:
     Square(double S) : SideLength(S) {}
     double computeArea() override;
   };

   class Circle : public Shape {
     double Radius;
   public:
     Circle(double R) : Radius(R) {}
     double computeArea() override;
   };

The most basic working setup for LLVM-style RTTI requires the following
steps:

#. In the header where you declare ``Shape``, you will want to ``#include
   "llvm/Support/Casting.h"``, which declares LLVM's RTTI templates. That
   way your clients don't even have to think about it.

   .. code-block:: c++

      #include "llvm/Support/Casting.h"

#. In the base class, introduce an enum which discriminates all of the
   different concrete classes in the hierarchy, and stash the enum value
   somewhere in the base class.

   Here is the code after introducing this change:

   .. code-block:: c++

       class Shape {
       public:
      +  /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
      +  enum ShapeKind {
      +    SK_Square,
      +    SK_Circle
      +  };
      +private:
      +  const ShapeKind Kind;
      +public:
      +  ShapeKind getKind() const { return Kind; }
      +
         Shape() {}
         virtual double computeArea() = 0;
       };

   You will usually want to keep the ``Kind`` member encapsulated and
   private, but let the enum ``ShapeKind`` be public along with providing a
   ``getKind()`` method. This is convenient for clients so that they can do
   a ``switch`` over the enum.

   A common naming convention is that these enums are "kind"s, to avoid
   ambiguity with the words "type" or "class" which have overloaded meanings
   in many contexts within LLVM. Sometimes there will be a natural name for
   it, like "opcode". Don't bikeshed over this; when in doubt use ``Kind``.

   You might wonder why the ``Kind`` enum doesn't have an entry for
   ``Shape``. The reason for this is that since ``Shape`` is abstract
   (``computeArea() = 0;``), you will never actually have non-derived
   instances of exactly that class (only subclasses). See `Concrete Bases
   and Deeper Hierarchies`_ for information on how to deal with
   non-abstract bases. It's worth mentioning here that unlike
   ``dynamic_cast<>``, LLVM-style RTTI can be used (and is often used) for
   classes that don't have v-tables.

#. Next, you need to make sure that the ``Kind`` gets initialized to the
   value corresponding to the dynamic type of the class. Typically, you will
   want to have it be an argument to the constructor of the base class, and
   then pass in the respective ``XXXKind`` from subclass constructors.

   Here is the code after that change:

   .. code-block:: c++

       class Shape {
       public:
         /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
         enum ShapeKind {
           SK_Square,
           SK_Circle
         };
       private:
         const ShapeKind Kind;
       public:
         ShapeKind getKind() const { return Kind; }

      -  Shape() {}
      +  Shape(ShapeKind K) : Kind(K) {}
         virtual double computeArea() = 0;
       };

       class Square : public Shape {
         double SideLength;
       public:
      -  Square(double S) : SideLength(S) {}
      +  Square(double S) : Shape(SK_Square), SideLength(S) {}
         double computeArea() override;
       };

       class Circle : public Shape {
         double Radius;
       public:
      -  Circle(double R) : Radius(R) {}
      +  Circle(double R) : Shape(SK_Circle), Radius(R) {}
         double computeArea() override;
       };

#. Finally, you need to inform LLVM's RTTI templates how to dynamically
   determine the type of a class (i.e. whether the ``isa<>``/``dyn_cast<>``
   should succeed). The default "99.9% of use cases" way to accomplish this
   is through a small static member function ``classof``. In order to have
   proper context for an explanation, we will display this code first, and
   then below describe each part:

   .. code-block:: c++

       class Shape {
       public:
         /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
         enum ShapeKind {
           SK_Square,
           SK_Circle
         };
       private:
         const ShapeKind Kind;
       public:
         ShapeKind getKind() const { return Kind; }

         Shape(ShapeKind K) : Kind(K) {}
         virtual double computeArea() = 0;
       };

       class Square : public Shape {
         double SideLength;
       public:
         Square(double S) : Shape(SK_Square), SideLength(S) {}
         double computeArea() override;
      +
      +  static bool classof(const Shape *S) {
      +    return S->getKind() == SK_Square;
      +  }
       };

       class Circle : public Shape {
         double Radius;
       public:
         Circle(double R) : Shape(SK_Circle), Radius(R) {}
         double computeArea() override;
      +
      +  static bool classof(const Shape *S) {
      +    return S->getKind() == SK_Circle;
      +  }
       };

   The job of ``classof`` is to dynamically determine whether an object of
   a base class is in fact of a particular derived class.  In order to
   downcast a type ``Base`` to a type ``Derived``, there needs to be a
   ``classof`` in ``Derived`` which will accept an object of type ``Base``.

   To be concrete, consider the following code:

   .. code-block:: c++

      Shape *S = ...;
      if (isa<Circle>(S)) {
        /* do something ... */
      }

   The code of the ``isa<>`` test in this code will eventually boil
   down---after template instantiation and some other machinery---to a
   check roughly like ``Circle::classof(S)``. For more information, see
   :ref:`classof-contract`.

   The argument to ``classof`` should always be an *ancestor* class because
   the implementation has logic to allow and optimize away
   upcasts/up-``isa<>``'s automatically. It is as though every class
   ``Foo`` automatically has a ``classof`` like:

   .. code-block:: c++

      class Foo {
        [...]
        template <class T>
        static bool classof(const T *,
                            ::std::enable_if<
                              ::std::is_base_of<Foo, T>::value
                            >::type* = 0) { return true; }
        [...]
      };

   Note that this is the reason that we did not need to introduce a
   ``classof`` into ``Shape``: all relevant classes derive from ``Shape``,
   and ``Shape`` itself is abstract (has no entry in the ``Kind`` enum),
   so this notional inferred ``classof`` is all we need. See `Concrete
   Bases and Deeper Hierarchies`_ for more information about how to extend
   this example to more general hierarchies.

Although for this small example setting up LLVM-style RTTI seems like a lot
of "boilerplate", if your classes are doing anything interesting then this
will end up being a tiny fraction of the code.

Concrete Bases and Deeper Hierarchies
=====================================

For concrete bases (i.e. non-abstract interior nodes of the inheritance
tree), the ``Kind`` check inside ``classof`` needs to be a bit more
complicated. The situation differs from the example above in that

* Since the class is concrete, it must itself have an entry in the ``Kind``
  enum because it is possible to have objects with this class as a dynamic
  type.

* Since the class has children, the check inside ``classof`` must take them
  into account.

Say that ``SpecialSquare`` and ``OtherSpecialSquare`` derive
from ``Square``, and so ``ShapeKind`` becomes:

.. code-block:: c++

    enum ShapeKind {
      SK_Square,
   +  SK_SpecialSquare,
   +  SK_OtherSpecialSquare,
      SK_Circle
    }

Then in ``Square``, we would need to modify the ``classof`` like so:

.. code-block:: c++

   -  static bool classof(const Shape *S) {
   -    return S->getKind() == SK_Square;
   -  }
   +  static bool classof(const Shape *S) {
   +    return S->getKind() >= SK_Square &&
   +           S->getKind() <= SK_OtherSpecialSquare;
   +  }

The reason that we need to test a range like this instead of just equality
is that both ``SpecialSquare`` and ``OtherSpecialSquare`` "is-a"
``Square``, and so ``classof`` needs to return ``true`` for them.

This approach can be made to scale to arbitrarily deep hierarchies. The
trick is that you arrange the enum values so that they correspond to a
preorder traversal of the class hierarchy tree. With that arrangement, all
subclass tests can be done with two comparisons as shown above. If you just
list the class hierarchy like a list of bullet points, you'll get the
ordering right::

   | Shape
     | Square
       | SpecialSquare
       | OtherSpecialSquare
     | Circle

A Bug to be Aware Of
--------------------

The example just given opens the door to bugs where the ``classof``\s are
not updated to match the ``Kind`` enum when adding (or removing) classes to
(from) the hierarchy.

Continuing the example above, suppose we add a ``SomewhatSpecialSquare`` as
a subclass of ``Square``, and update the ``ShapeKind`` enum like so:

.. code-block:: c++

    enum ShapeKind {
      SK_Square,
      SK_SpecialSquare,
      SK_OtherSpecialSquare,
   +  SK_SomewhatSpecialSquare,
      SK_Circle
    }

Now, suppose that we forget to update ``Square::classof()``, so it still
looks like:

.. code-block:: c++

   static bool classof(const Shape *S) {
     // BUG: Returns false when S->getKind() == SK_SomewhatSpecialSquare,
     // even though SomewhatSpecialSquare "is a" Square.
     return S->getKind() >= SK_Square &&
            S->getKind() <= SK_OtherSpecialSquare;
   }

As the comment indicates, this code contains a bug. A straightforward and
non-clever way to avoid this is to introduce an explicit ``SK_LastSquare``
entry in the enum when adding the first subclass(es). For example, we could
rewrite the example at the beginning of `Concrete Bases and Deeper
Hierarchies`_ as:

.. code-block:: c++

    enum ShapeKind {
      SK_Square,
   +  SK_SpecialSquare,
   +  SK_OtherSpecialSquare,
   +  SK_LastSquare,
      SK_Circle
    }
   ...
   // Square::classof()
   -  static bool classof(const Shape *S) {
   -    return S->getKind() == SK_Square;
   -  }
   +  static bool classof(const Shape *S) {
   +    return S->getKind() >= SK_Square &&
   +           S->getKind() <= SK_LastSquare;
   +  }

Then, adding new subclasses is easy:

.. code-block:: c++

    enum ShapeKind {
      SK_Square,
      SK_SpecialSquare,
      SK_OtherSpecialSquare,
   +  SK_SomewhatSpecialSquare,
      SK_LastSquare,
      SK_Circle
    }

Notice that ``Square::classof`` does not need to be changed.

.. _classof-contract:

The Contract of ``classof``
---------------------------

To be more precise, let ``classof`` be inside a class ``C``.  Then the
contract for ``classof`` is "return ``true`` if the dynamic type of the
argument is-a ``C``".  As long as your implementation fulfills this
contract, you can tweak and optimize it as much as you want.

For example, LLVM-style RTTI can work fine in the presence of
multiple-inheritance by defining an appropriate ``classof``.
An example of this in practice is
`Decl <https://clang.llvm.org/doxygen/classclang_1_1Decl.html>`_ vs.
`DeclContext <https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html>`_
inside Clang.
The ``Decl`` hierarchy is done very similarly to the example setup
demonstrated in this tutorial.
The key part is how to then incorporate ``DeclContext``: all that is needed
is in ``bool DeclContext::classof(const Decl *)``, which asks the question
"Given a ``Decl``, how can I determine if it is-a ``DeclContext``?".
It answers this with a simple switch over the set of ``Decl`` "kinds", and
returning true for ones that are known to be ``DeclContext``'s.

.. TODO::

   Touch on some of the more advanced features, like ``isa_impl`` and
   ``simplify_type``. However, those two need reference documentation in
   the form of doxygen comments as well. We need the doxygen so that we can
   say "for full details, see https://llvm.org/doxygen/..."

Rules of Thumb
==============

#. The ``Kind`` enum should have one entry per concrete class, ordered
   according to a preorder traversal of the inheritance tree.
#. The argument to ``classof`` should be a ``const Base *``, where ``Base``
   is some ancestor in the inheritance hierarchy. The argument should
   *never* be a derived class or the class itself: the template machinery
   for ``isa<>`` already handles this case and optimizes it.
#. For each class in the hierarchy that has no children, implement a
   ``classof`` that checks only against its ``Kind``.
#. For each class in the hierarchy that has children, implement a
   ``classof`` that checks a range of the first child's ``Kind`` and the
   last child's ``Kind``.

RTTI for Open Class Hierarchies
===============================

Sometimes it is not possible to know all types in a hierarchy ahead of time.
For example, in the shapes hierarchy described above the authors may have
wanted their code to work for user defined shapes too. To support use cases
that require open hierarchies LLVM provides the ``RTTIRoot`` and
``RTTIExtends`` utilities.

The ``RTTIRoot`` class describes an interface for performing RTTI checks. The
``RTTIExtends`` class template provides an implementation of this interface
for classes derived from ``RTTIRoot``. ``RTTIExtends`` uses the "`Curiously
Recurring Template Idiom`_", taking the class being defined as its first
template argument and the parent class as the second argument. Any class that
uses ``RTTIExtends`` must define a ``static char ID`` member, the address of
which will be used to identify the type.

This open-hierarchy RTTI support should only be used if your use case requires
it. Otherwise the standard LLVM RTTI system should be preferred.

.. _`Curiously Recurring Template Idiom`:
  https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

E.g.

.. code-block:: c++

   class Shape : public RTTIExtends<Shape, RTTIRoot> {
   public:
     static char ID;
     virtual double computeArea() = 0;
   };

   class Square : public RTTIExtends<Square, Shape> {
     double SideLength;
   public:
     static char ID;

     Square(double S) : SideLength(S) {}
     double computeArea() override;
   };

   class Circle : public RTTIExtends<Circle, Shape> {
     double Radius;
   public:
     static char ID;

     Circle(double R) : Radius(R) {}
     double computeArea() override;
   };

   char Shape::ID = 0;
   char Square::ID = 0;
   char Circle::ID = 0;

Advanced Use Cases
==================

The underlying implementation of isa/cast/dyn_cast is all controlled through a
struct called ``CastInfo``. ``CastInfo`` provides 4 methods, ``isPossible``,
``doCast``, ``castFailed``, and ``doCastIfPossible``. These are for ``isa``,
``cast``, and ``dyn_cast``, in order. You can control the way your cast is
performed by creating a specialization of the ``CastInfo`` struct (to your
desired types) that provides the same static methods as the base ``CastInfo``
struct.

This can be a lot of boilerplate, so we also have what we call Cast Traits.
These are structs that provide one or more of the above methods so you can
factor out common casting patterns in your project. We provide a few in the
header file ready to be used, and we'll show a few examples motivating their
usage. These examples are not exhaustive, and adding new cast traits is easy
so users should feel free to add them to their project, or contribute them if
they're particularly useful!

Value to value casting
----------------------
In this case, we have a struct that is what we call 'nullable' - i.e. it is
constructible from ``nullptr`` and that results in a value you can tell is
invalid.

.. code-block:: c++

  class SomeValue {
  public:
    SomeValue(void *ptr) : ptr(ptr) {}
    void *getPointer() const { return ptr; }
    bool isValid() const { return ptr != nullptr; }
  private:
    void *ptr;
  };

Given something like this, we want to pass this object around by value, and we
would like to cast from objects of this type to some other set of objects. For
now, we assume that the types we want to cast *to* all provide ``classof``. So
we can use some provided cast traits like so:

.. code-block:: c++

  template <typename T>
  struct CastInfo<T, SomeValue>
    : CastIsPossible<T, SomeValue>, NullableValueCastFailed<T>,
      DefaultDoCastIfPossible<T, SomeValue, CastInfo<T, SomeValue>> {
    static T doCast(SomeValue v) {
      return T(v.getPointer());
    }
  };

Pointer to value casting
------------------------
Now given the value above ``SomeValue``, maybe we'd like to be able to cast to
that type from a char pointer type. So what we would do in that case is:

.. code-block:: c++

  template <typename T>
  struct CastInfo<SomeValue, T *>
    : NullableValueCastFailed<SomeValue>,
      DefaultDoCastIfPossible<SomeValue, T *, CastInfo<SomeValue, T *>> {
    static bool isPossible(const T *t) {
      return std::is_same<T, char>::value;
    }
    static SomeValue doCast(const T *t) {
      return SomeValue((void *)t);
    }
  };

This would enable us to cast from a ``char *`` to a SomeValue, if we wanted to.

Optional value casting
----------------------
When your types are not constructible from ``nullptr`` or there isn't a simple
way to tell when an object is invalid, you may want to use ``llvm::Optional``.
In those cases, you probably want something like this:

.. code-block:: c++

  template <typename T>
  struct CastInfo<T, SomeValue> : OptionalValueCast<T, SomeValue> {};

That cast trait requires that ``T`` is constructible from ``const SomeValue &``
but it enables casting like so:

.. code-block:: c++

  SomeValue someVal = ...;
  Optional<AnotherValue> valOr = dyn_cast<AnotherValue>(someVal);

With the ``_if_present`` variants, you can even do optional chaining like this:

.. code-block:: c++

  Optional<SomeValue> someVal = ...;
  Optional<AnotherValue> valOr = dyn_cast_if_present<AnotherValue>(someVal);

and ``valOr`` will be ``None`` if either ``someVal`` cannot be converted *or*
if ``someVal`` was also ``None``.
