1*9880d681SAndroid Build Coastguard Worker====================================================== 2*9880d681SAndroid Build Coastguard WorkerHow to set up LLVM-style RTTI for your class hierarchy 3*9880d681SAndroid Build Coastguard Worker====================================================== 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker.. contents:: 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard WorkerBackground 8*9880d681SAndroid Build Coastguard Worker========== 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard WorkerLLVM avoids using C++'s built in RTTI. Instead, it pervasively uses its 11*9880d681SAndroid Build Coastguard Workerown hand-rolled form of RTTI which is much more efficient and flexible, 12*9880d681SAndroid Build Coastguard Workeralthough it requires a bit more work from you as a class author. 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard WorkerA description of how to use LLVM-style RTTI from a client's perspective is 15*9880d681SAndroid Build Coastguard Workergiven in the `Programmer's Manual <ProgrammersManual.html#isa>`_. This 16*9880d681SAndroid Build Coastguard Workerdocument, in contrast, discusses the steps you need to take as a class 17*9880d681SAndroid Build Coastguard Workerhierarchy author to make LLVM-style RTTI available to your clients. 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard WorkerBefore diving in, make sure that you are familiar with the Object Oriented 20*9880d681SAndroid Build Coastguard WorkerProgramming concept of "`is-a`_". 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker.. _is-a: http://en.wikipedia.org/wiki/Is-a 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard WorkerBasic Setup 25*9880d681SAndroid Build Coastguard Worker=========== 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard WorkerThis section describes how to set up the most basic form of LLVM-style RTTI 28*9880d681SAndroid Build Coastguard Worker(which is sufficient for 99.9% of the cases). We will set up LLVM-style 29*9880d681SAndroid Build Coastguard WorkerRTTI for this class hierarchy: 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker class Shape { 34*9880d681SAndroid Build Coastguard Worker public: 35*9880d681SAndroid Build Coastguard Worker Shape() {} 36*9880d681SAndroid Build Coastguard Worker virtual double computeArea() = 0; 37*9880d681SAndroid Build Coastguard Worker }; 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker class Square : public Shape { 40*9880d681SAndroid Build Coastguard Worker double SideLength; 41*9880d681SAndroid Build Coastguard Worker public: 42*9880d681SAndroid Build Coastguard Worker Square(double S) : SideLength(S) {} 43*9880d681SAndroid Build Coastguard Worker double computeArea() override; 44*9880d681SAndroid Build Coastguard Worker }; 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker class Circle : public Shape { 47*9880d681SAndroid Build Coastguard Worker double Radius; 48*9880d681SAndroid Build Coastguard Worker public: 49*9880d681SAndroid Build Coastguard Worker Circle(double R) : Radius(R) {} 50*9880d681SAndroid Build Coastguard Worker double computeArea() override; 51*9880d681SAndroid Build Coastguard Worker }; 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard WorkerThe most basic working setup for LLVM-style RTTI requires the following 54*9880d681SAndroid Build Coastguard Workersteps: 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker#. In the header where you declare ``Shape``, you will want to ``#include 57*9880d681SAndroid Build Coastguard Worker "llvm/Support/Casting.h"``, which declares LLVM's RTTI templates. That 58*9880d681SAndroid Build Coastguard Worker way your clients don't even have to think about it. 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h" 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker#. In the base class, introduce an enum which discriminates all of the 65*9880d681SAndroid Build Coastguard Worker different concrete classes in the hierarchy, and stash the enum value 66*9880d681SAndroid Build Coastguard Worker somewhere in the base class. 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker Here is the code after introducing this change: 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker class Shape { 73*9880d681SAndroid Build Coastguard Worker public: 74*9880d681SAndroid Build Coastguard Worker + /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.) 75*9880d681SAndroid Build Coastguard Worker + enum ShapeKind { 76*9880d681SAndroid Build Coastguard Worker + SK_Square, 77*9880d681SAndroid Build Coastguard Worker + SK_Circle 78*9880d681SAndroid Build Coastguard Worker + }; 79*9880d681SAndroid Build Coastguard Worker +private: 80*9880d681SAndroid Build Coastguard Worker + const ShapeKind Kind; 81*9880d681SAndroid Build Coastguard Worker +public: 82*9880d681SAndroid Build Coastguard Worker + ShapeKind getKind() const { return Kind; } 83*9880d681SAndroid Build Coastguard Worker + 84*9880d681SAndroid Build Coastguard Worker Shape() {} 85*9880d681SAndroid Build Coastguard Worker virtual double computeArea() = 0; 86*9880d681SAndroid Build Coastguard Worker }; 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker You will usually want to keep the ``Kind`` member encapsulated and 89*9880d681SAndroid Build Coastguard Worker private, but let the enum ``ShapeKind`` be public along with providing a 90*9880d681SAndroid Build Coastguard Worker ``getKind()`` method. This is convenient for clients so that they can do 91*9880d681SAndroid Build Coastguard Worker a ``switch`` over the enum. 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker A common naming convention is that these enums are "kind"s, to avoid 94*9880d681SAndroid Build Coastguard Worker ambiguity with the words "type" or "class" which have overloaded meanings 95*9880d681SAndroid Build Coastguard Worker in many contexts within LLVM. Sometimes there will be a natural name for 96*9880d681SAndroid Build Coastguard Worker it, like "opcode". Don't bikeshed over this; when in doubt use ``Kind``. 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker You might wonder why the ``Kind`` enum doesn't have an entry for 99*9880d681SAndroid Build Coastguard Worker ``Shape``. The reason for this is that since ``Shape`` is abstract 100*9880d681SAndroid Build Coastguard Worker (``computeArea() = 0;``), you will never actually have non-derived 101*9880d681SAndroid Build Coastguard Worker instances of exactly that class (only subclasses). See `Concrete Bases 102*9880d681SAndroid Build Coastguard Worker and Deeper Hierarchies`_ for information on how to deal with 103*9880d681SAndroid Build Coastguard Worker non-abstract bases. It's worth mentioning here that unlike 104*9880d681SAndroid Build Coastguard Worker ``dynamic_cast<>``, LLVM-style RTTI can be used (and is often used) for 105*9880d681SAndroid Build Coastguard Worker classes that don't have v-tables. 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker#. Next, you need to make sure that the ``Kind`` gets initialized to the 108*9880d681SAndroid Build Coastguard Worker value corresponding to the dynamic type of the class. Typically, you will 109*9880d681SAndroid Build Coastguard Worker want to have it be an argument to the constructor of the base class, and 110*9880d681SAndroid Build Coastguard Worker then pass in the respective ``XXXKind`` from subclass constructors. 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker Here is the code after that change: 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker class Shape { 117*9880d681SAndroid Build Coastguard Worker public: 118*9880d681SAndroid Build Coastguard Worker /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.) 119*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 120*9880d681SAndroid Build Coastguard Worker SK_Square, 121*9880d681SAndroid Build Coastguard Worker SK_Circle 122*9880d681SAndroid Build Coastguard Worker }; 123*9880d681SAndroid Build Coastguard Worker private: 124*9880d681SAndroid Build Coastguard Worker const ShapeKind Kind; 125*9880d681SAndroid Build Coastguard Worker public: 126*9880d681SAndroid Build Coastguard Worker ShapeKind getKind() const { return Kind; } 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker - Shape() {} 129*9880d681SAndroid Build Coastguard Worker + Shape(ShapeKind K) : Kind(K) {} 130*9880d681SAndroid Build Coastguard Worker virtual double computeArea() = 0; 131*9880d681SAndroid Build Coastguard Worker }; 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker class Square : public Shape { 134*9880d681SAndroid Build Coastguard Worker double SideLength; 135*9880d681SAndroid Build Coastguard Worker public: 136*9880d681SAndroid Build Coastguard Worker - Square(double S) : SideLength(S) {} 137*9880d681SAndroid Build Coastguard Worker + Square(double S) : Shape(SK_Square), SideLength(S) {} 138*9880d681SAndroid Build Coastguard Worker double computeArea() override; 139*9880d681SAndroid Build Coastguard Worker }; 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker class Circle : public Shape { 142*9880d681SAndroid Build Coastguard Worker double Radius; 143*9880d681SAndroid Build Coastguard Worker public: 144*9880d681SAndroid Build Coastguard Worker - Circle(double R) : Radius(R) {} 145*9880d681SAndroid Build Coastguard Worker + Circle(double R) : Shape(SK_Circle), Radius(R) {} 146*9880d681SAndroid Build Coastguard Worker double computeArea() override; 147*9880d681SAndroid Build Coastguard Worker }; 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker#. Finally, you need to inform LLVM's RTTI templates how to dynamically 150*9880d681SAndroid Build Coastguard Worker determine the type of a class (i.e. whether the ``isa<>``/``dyn_cast<>`` 151*9880d681SAndroid Build Coastguard Worker should succeed). The default "99.9% of use cases" way to accomplish this 152*9880d681SAndroid Build Coastguard Worker is through a small static member function ``classof``. In order to have 153*9880d681SAndroid Build Coastguard Worker proper context for an explanation, we will display this code first, and 154*9880d681SAndroid Build Coastguard Worker then below describe each part: 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker class Shape { 159*9880d681SAndroid Build Coastguard Worker public: 160*9880d681SAndroid Build Coastguard Worker /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.) 161*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 162*9880d681SAndroid Build Coastguard Worker SK_Square, 163*9880d681SAndroid Build Coastguard Worker SK_Circle 164*9880d681SAndroid Build Coastguard Worker }; 165*9880d681SAndroid Build Coastguard Worker private: 166*9880d681SAndroid Build Coastguard Worker const ShapeKind Kind; 167*9880d681SAndroid Build Coastguard Worker public: 168*9880d681SAndroid Build Coastguard Worker ShapeKind getKind() const { return Kind; } 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker Shape(ShapeKind K) : Kind(K) {} 171*9880d681SAndroid Build Coastguard Worker virtual double computeArea() = 0; 172*9880d681SAndroid Build Coastguard Worker }; 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker class Square : public Shape { 175*9880d681SAndroid Build Coastguard Worker double SideLength; 176*9880d681SAndroid Build Coastguard Worker public: 177*9880d681SAndroid Build Coastguard Worker Square(double S) : Shape(SK_Square), SideLength(S) {} 178*9880d681SAndroid Build Coastguard Worker double computeArea() override; 179*9880d681SAndroid Build Coastguard Worker + 180*9880d681SAndroid Build Coastguard Worker + static bool classof(const Shape *S) { 181*9880d681SAndroid Build Coastguard Worker + return S->getKind() == SK_Square; 182*9880d681SAndroid Build Coastguard Worker + } 183*9880d681SAndroid Build Coastguard Worker }; 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker class Circle : public Shape { 186*9880d681SAndroid Build Coastguard Worker double Radius; 187*9880d681SAndroid Build Coastguard Worker public: 188*9880d681SAndroid Build Coastguard Worker Circle(double R) : Shape(SK_Circle), Radius(R) {} 189*9880d681SAndroid Build Coastguard Worker double computeArea() override; 190*9880d681SAndroid Build Coastguard Worker + 191*9880d681SAndroid Build Coastguard Worker + static bool classof(const Shape *S) { 192*9880d681SAndroid Build Coastguard Worker + return S->getKind() == SK_Circle; 193*9880d681SAndroid Build Coastguard Worker + } 194*9880d681SAndroid Build Coastguard Worker }; 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker The job of ``classof`` is to dynamically determine whether an object of 197*9880d681SAndroid Build Coastguard Worker a base class is in fact of a particular derived class. In order to 198*9880d681SAndroid Build Coastguard Worker downcast a type ``Base`` to a type ``Derived``, there needs to be a 199*9880d681SAndroid Build Coastguard Worker ``classof`` in ``Derived`` which will accept an object of type ``Base``. 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Worker To be concrete, consider the following code: 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker Shape *S = ...; 206*9880d681SAndroid Build Coastguard Worker if (isa<Circle>(S)) { 207*9880d681SAndroid Build Coastguard Worker /* do something ... */ 208*9880d681SAndroid Build Coastguard Worker } 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker The code of the ``isa<>`` test in this code will eventually boil 211*9880d681SAndroid Build Coastguard Worker down---after template instantiation and some other machinery---to a 212*9880d681SAndroid Build Coastguard Worker check roughly like ``Circle::classof(S)``. For more information, see 213*9880d681SAndroid Build Coastguard Worker :ref:`classof-contract`. 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker The argument to ``classof`` should always be an *ancestor* class because 216*9880d681SAndroid Build Coastguard Worker the implementation has logic to allow and optimize away 217*9880d681SAndroid Build Coastguard Worker upcasts/up-``isa<>``'s automatically. It is as though every class 218*9880d681SAndroid Build Coastguard Worker ``Foo`` automatically has a ``classof`` like: 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Worker .. code-block:: c++ 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker class Foo { 223*9880d681SAndroid Build Coastguard Worker [...] 224*9880d681SAndroid Build Coastguard Worker template <class T> 225*9880d681SAndroid Build Coastguard Worker static bool classof(const T *, 226*9880d681SAndroid Build Coastguard Worker ::std::enable_if< 227*9880d681SAndroid Build Coastguard Worker ::std::is_base_of<Foo, T>::value 228*9880d681SAndroid Build Coastguard Worker >::type* = 0) { return true; } 229*9880d681SAndroid Build Coastguard Worker [...] 230*9880d681SAndroid Build Coastguard Worker }; 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker Note that this is the reason that we did not need to introduce a 233*9880d681SAndroid Build Coastguard Worker ``classof`` into ``Shape``: all relevant classes derive from ``Shape``, 234*9880d681SAndroid Build Coastguard Worker and ``Shape`` itself is abstract (has no entry in the ``Kind`` enum), 235*9880d681SAndroid Build Coastguard Worker so this notional inferred ``classof`` is all we need. See `Concrete 236*9880d681SAndroid Build Coastguard Worker Bases and Deeper Hierarchies`_ for more information about how to extend 237*9880d681SAndroid Build Coastguard Worker this example to more general hierarchies. 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard WorkerAlthough for this small example setting up LLVM-style RTTI seems like a lot 240*9880d681SAndroid Build Coastguard Workerof "boilerplate", if your classes are doing anything interesting then this 241*9880d681SAndroid Build Coastguard Workerwill end up being a tiny fraction of the code. 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard WorkerConcrete Bases and Deeper Hierarchies 244*9880d681SAndroid Build Coastguard Worker===================================== 245*9880d681SAndroid Build Coastguard Worker 246*9880d681SAndroid Build Coastguard WorkerFor concrete bases (i.e. non-abstract interior nodes of the inheritance 247*9880d681SAndroid Build Coastguard Workertree), the ``Kind`` check inside ``classof`` needs to be a bit more 248*9880d681SAndroid Build Coastguard Workercomplicated. The situation differs from the example above in that 249*9880d681SAndroid Build Coastguard Worker 250*9880d681SAndroid Build Coastguard Worker* Since the class is concrete, it must itself have an entry in the ``Kind`` 251*9880d681SAndroid Build Coastguard Worker enum because it is possible to have objects with this class as a dynamic 252*9880d681SAndroid Build Coastguard Worker type. 253*9880d681SAndroid Build Coastguard Worker 254*9880d681SAndroid Build Coastguard Worker* Since the class has children, the check inside ``classof`` must take them 255*9880d681SAndroid Build Coastguard Worker into account. 256*9880d681SAndroid Build Coastguard Worker 257*9880d681SAndroid Build Coastguard WorkerSay that ``SpecialSquare`` and ``OtherSpecialSquare`` derive 258*9880d681SAndroid Build Coastguard Workerfrom ``Square``, and so ``ShapeKind`` becomes: 259*9880d681SAndroid Build Coastguard Worker 260*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 261*9880d681SAndroid Build Coastguard Worker 262*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 263*9880d681SAndroid Build Coastguard Worker SK_Square, 264*9880d681SAndroid Build Coastguard Worker + SK_SpecialSquare, 265*9880d681SAndroid Build Coastguard Worker + SK_OtherSpecialSquare, 266*9880d681SAndroid Build Coastguard Worker SK_Circle 267*9880d681SAndroid Build Coastguard Worker } 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard WorkerThen in ``Square``, we would need to modify the ``classof`` like so: 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 272*9880d681SAndroid Build Coastguard Worker 273*9880d681SAndroid Build Coastguard Worker - static bool classof(const Shape *S) { 274*9880d681SAndroid Build Coastguard Worker - return S->getKind() == SK_Square; 275*9880d681SAndroid Build Coastguard Worker - } 276*9880d681SAndroid Build Coastguard Worker + static bool classof(const Shape *S) { 277*9880d681SAndroid Build Coastguard Worker + return S->getKind() >= SK_Square && 278*9880d681SAndroid Build Coastguard Worker + S->getKind() <= SK_OtherSpecialSquare; 279*9880d681SAndroid Build Coastguard Worker + } 280*9880d681SAndroid Build Coastguard Worker 281*9880d681SAndroid Build Coastguard WorkerThe reason that we need to test a range like this instead of just equality 282*9880d681SAndroid Build Coastguard Workeris that both ``SpecialSquare`` and ``OtherSpecialSquare`` "is-a" 283*9880d681SAndroid Build Coastguard Worker``Square``, and so ``classof`` needs to return ``true`` for them. 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard WorkerThis approach can be made to scale to arbitrarily deep hierarchies. The 286*9880d681SAndroid Build Coastguard Workertrick is that you arrange the enum values so that they correspond to a 287*9880d681SAndroid Build Coastguard Workerpreorder traversal of the class hierarchy tree. With that arrangement, all 288*9880d681SAndroid Build Coastguard Workersubclass tests can be done with two comparisons as shown above. If you just 289*9880d681SAndroid Build Coastguard Workerlist the class hierarchy like a list of bullet points, you'll get the 290*9880d681SAndroid Build Coastguard Workerordering right:: 291*9880d681SAndroid Build Coastguard Worker 292*9880d681SAndroid Build Coastguard Worker | Shape 293*9880d681SAndroid Build Coastguard Worker | Square 294*9880d681SAndroid Build Coastguard Worker | SpecialSquare 295*9880d681SAndroid Build Coastguard Worker | OtherSpecialSquare 296*9880d681SAndroid Build Coastguard Worker | Circle 297*9880d681SAndroid Build Coastguard Worker 298*9880d681SAndroid Build Coastguard WorkerA Bug to be Aware Of 299*9880d681SAndroid Build Coastguard Worker-------------------- 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard WorkerThe example just given opens the door to bugs where the ``classof``\s are 302*9880d681SAndroid Build Coastguard Workernot updated to match the ``Kind`` enum when adding (or removing) classes to 303*9880d681SAndroid Build Coastguard Worker(from) the hierarchy. 304*9880d681SAndroid Build Coastguard Worker 305*9880d681SAndroid Build Coastguard WorkerContinuing the example above, suppose we add a ``SomewhatSpecialSquare`` as 306*9880d681SAndroid Build Coastguard Workera subclass of ``Square``, and update the ``ShapeKind`` enum like so: 307*9880d681SAndroid Build Coastguard Worker 308*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 311*9880d681SAndroid Build Coastguard Worker SK_Square, 312*9880d681SAndroid Build Coastguard Worker SK_SpecialSquare, 313*9880d681SAndroid Build Coastguard Worker SK_OtherSpecialSquare, 314*9880d681SAndroid Build Coastguard Worker + SK_SomewhatSpecialSquare, 315*9880d681SAndroid Build Coastguard Worker SK_Circle 316*9880d681SAndroid Build Coastguard Worker } 317*9880d681SAndroid Build Coastguard Worker 318*9880d681SAndroid Build Coastguard WorkerNow, suppose that we forget to update ``Square::classof()``, so it still 319*9880d681SAndroid Build Coastguard Workerlooks like: 320*9880d681SAndroid Build Coastguard Worker 321*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 322*9880d681SAndroid Build Coastguard Worker 323*9880d681SAndroid Build Coastguard Worker static bool classof(const Shape *S) { 324*9880d681SAndroid Build Coastguard Worker // BUG: Returns false when S->getKind() == SK_SomewhatSpecialSquare, 325*9880d681SAndroid Build Coastguard Worker // even though SomewhatSpecialSquare "is a" Square. 326*9880d681SAndroid Build Coastguard Worker return S->getKind() >= SK_Square && 327*9880d681SAndroid Build Coastguard Worker S->getKind() <= SK_OtherSpecialSquare; 328*9880d681SAndroid Build Coastguard Worker } 329*9880d681SAndroid Build Coastguard Worker 330*9880d681SAndroid Build Coastguard WorkerAs the comment indicates, this code contains a bug. A straightforward and 331*9880d681SAndroid Build Coastguard Workernon-clever way to avoid this is to introduce an explicit ``SK_LastSquare`` 332*9880d681SAndroid Build Coastguard Workerentry in the enum when adding the first subclass(es). For example, we could 333*9880d681SAndroid Build Coastguard Workerrewrite the example at the beginning of `Concrete Bases and Deeper 334*9880d681SAndroid Build Coastguard WorkerHierarchies`_ as: 335*9880d681SAndroid Build Coastguard Worker 336*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 337*9880d681SAndroid Build Coastguard Worker 338*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 339*9880d681SAndroid Build Coastguard Worker SK_Square, 340*9880d681SAndroid Build Coastguard Worker + SK_SpecialSquare, 341*9880d681SAndroid Build Coastguard Worker + SK_OtherSpecialSquare, 342*9880d681SAndroid Build Coastguard Worker + SK_LastSquare, 343*9880d681SAndroid Build Coastguard Worker SK_Circle 344*9880d681SAndroid Build Coastguard Worker } 345*9880d681SAndroid Build Coastguard Worker ... 346*9880d681SAndroid Build Coastguard Worker // Square::classof() 347*9880d681SAndroid Build Coastguard Worker - static bool classof(const Shape *S) { 348*9880d681SAndroid Build Coastguard Worker - return S->getKind() == SK_Square; 349*9880d681SAndroid Build Coastguard Worker - } 350*9880d681SAndroid Build Coastguard Worker + static bool classof(const Shape *S) { 351*9880d681SAndroid Build Coastguard Worker + return S->getKind() >= SK_Square && 352*9880d681SAndroid Build Coastguard Worker + S->getKind() <= SK_LastSquare; 353*9880d681SAndroid Build Coastguard Worker + } 354*9880d681SAndroid Build Coastguard Worker 355*9880d681SAndroid Build Coastguard WorkerThen, adding new subclasses is easy: 356*9880d681SAndroid Build Coastguard Worker 357*9880d681SAndroid Build Coastguard Worker.. code-block:: c++ 358*9880d681SAndroid Build Coastguard Worker 359*9880d681SAndroid Build Coastguard Worker enum ShapeKind { 360*9880d681SAndroid Build Coastguard Worker SK_Square, 361*9880d681SAndroid Build Coastguard Worker SK_SpecialSquare, 362*9880d681SAndroid Build Coastguard Worker SK_OtherSpecialSquare, 363*9880d681SAndroid Build Coastguard Worker + SK_SomewhatSpecialSquare, 364*9880d681SAndroid Build Coastguard Worker SK_LastSquare, 365*9880d681SAndroid Build Coastguard Worker SK_Circle 366*9880d681SAndroid Build Coastguard Worker } 367*9880d681SAndroid Build Coastguard Worker 368*9880d681SAndroid Build Coastguard WorkerNotice that ``Square::classof`` does not need to be changed. 369*9880d681SAndroid Build Coastguard Worker 370*9880d681SAndroid Build Coastguard Worker.. _classof-contract: 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard WorkerThe Contract of ``classof`` 373*9880d681SAndroid Build Coastguard Worker--------------------------- 374*9880d681SAndroid Build Coastguard Worker 375*9880d681SAndroid Build Coastguard WorkerTo be more precise, let ``classof`` be inside a class ``C``. Then the 376*9880d681SAndroid Build Coastguard Workercontract for ``classof`` is "return ``true`` if the dynamic type of the 377*9880d681SAndroid Build Coastguard Workerargument is-a ``C``". As long as your implementation fulfills this 378*9880d681SAndroid Build Coastguard Workercontract, you can tweak and optimize it as much as you want. 379*9880d681SAndroid Build Coastguard Worker 380*9880d681SAndroid Build Coastguard WorkerFor example, LLVM-style RTTI can work fine in the presence of 381*9880d681SAndroid Build Coastguard Workermultiple-inheritance by defining an appropriate ``classof``. 382*9880d681SAndroid Build Coastguard WorkerAn example of this in practice is 383*9880d681SAndroid Build Coastguard Worker`Decl <http://clang.llvm.org/doxygen/classclang_1_1Decl.html>`_ vs. 384*9880d681SAndroid Build Coastguard Worker`DeclContext <http://clang.llvm.org/doxygen/classclang_1_1DeclContext.html>`_ 385*9880d681SAndroid Build Coastguard Workerinside Clang. 386*9880d681SAndroid Build Coastguard WorkerThe ``Decl`` hierarchy is done very similarly to the example setup 387*9880d681SAndroid Build Coastguard Workerdemonstrated in this tutorial. 388*9880d681SAndroid Build Coastguard WorkerThe key part is how to then incorporate ``DeclContext``: all that is needed 389*9880d681SAndroid Build Coastguard Workeris in ``bool DeclContext::classof(const Decl *)``, which asks the question 390*9880d681SAndroid Build Coastguard Worker"Given a ``Decl``, how can I determine if it is-a ``DeclContext``?". 391*9880d681SAndroid Build Coastguard WorkerIt answers this with a simple switch over the set of ``Decl`` "kinds", and 392*9880d681SAndroid Build Coastguard Workerreturning true for ones that are known to be ``DeclContext``'s. 393*9880d681SAndroid Build Coastguard Worker 394*9880d681SAndroid Build Coastguard Worker.. TODO:: 395*9880d681SAndroid Build Coastguard Worker 396*9880d681SAndroid Build Coastguard Worker Touch on some of the more advanced features, like ``isa_impl`` and 397*9880d681SAndroid Build Coastguard Worker ``simplify_type``. However, those two need reference documentation in 398*9880d681SAndroid Build Coastguard Worker the form of doxygen comments as well. We need the doxygen so that we can 399*9880d681SAndroid Build Coastguard Worker say "for full details, see http://llvm.org/doxygen/..." 400*9880d681SAndroid Build Coastguard Worker 401*9880d681SAndroid Build Coastguard WorkerRules of Thumb 402*9880d681SAndroid Build Coastguard Worker============== 403*9880d681SAndroid Build Coastguard Worker 404*9880d681SAndroid Build Coastguard Worker#. The ``Kind`` enum should have one entry per concrete class, ordered 405*9880d681SAndroid Build Coastguard Worker according to a preorder traversal of the inheritance tree. 406*9880d681SAndroid Build Coastguard Worker#. The argument to ``classof`` should be a ``const Base *``, where ``Base`` 407*9880d681SAndroid Build Coastguard Worker is some ancestor in the inheritance hierarchy. The argument should 408*9880d681SAndroid Build Coastguard Worker *never* be a derived class or the class itself: the template machinery 409*9880d681SAndroid Build Coastguard Worker for ``isa<>`` already handles this case and optimizes it. 410*9880d681SAndroid Build Coastguard Worker#. For each class in the hierarchy that has no children, implement a 411*9880d681SAndroid Build Coastguard Worker ``classof`` that checks only against its ``Kind``. 412*9880d681SAndroid Build Coastguard Worker#. For each class in the hierarchy that has children, implement a 413*9880d681SAndroid Build Coastguard Worker ``classof`` that checks a range of the first child's ``Kind`` and the 414*9880d681SAndroid Build Coastguard Worker last child's ``Kind``. 415