aboutsummaryrefslogtreecommitdiff
path: root/docs/HowToSetUpLLVMStyleRTTI.rst
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-04-03 14:07:16 +0000
committerAlexander Kornienko <alexfh@google.com>2013-04-03 14:07:16 +0000
commite133bc868944822bf8961f825d3aa63d6fa48fb7 (patch)
treeebbd4a8040181471467a9737d90d94dc6b58b316 /docs/HowToSetUpLLVMStyleRTTI.rst
parent647735c781c5b37061ee03d6e9e6c7dda92218e2 (diff)
parent080e3c523e87ec68ca1ea5db4cd49816028dd8bd (diff)
Updating branches/google/stable to r178511stable
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@178655 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/HowToSetUpLLVMStyleRTTI.rst')
-rw-r--r--docs/HowToSetUpLLVMStyleRTTI.rst72
1 files changed, 72 insertions, 0 deletions
diff --git a/docs/HowToSetUpLLVMStyleRTTI.rst b/docs/HowToSetUpLLVMStyleRTTI.rst
index b906b25621..e0f865a141 100644
--- a/docs/HowToSetUpLLVMStyleRTTI.rst
+++ b/docs/HowToSetUpLLVMStyleRTTI.rst
@@ -295,6 +295,78 @@ ordering right::
| 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``