aboutsummaryrefslogtreecommitdiff
path: root/docs/HowToSetUpLLVMStyleRTTI.rst
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-03-26 02:28:59 +0000
committerAlexander Kornienko <alexfh@google.com>2013-03-26 02:28:59 +0000
commitd934545ae6a00aa8a8179a93d11cbd93a5240849 (patch)
treeab44db08aa63a8f94a3e09d6491c4156c624af96 /docs/HowToSetUpLLVMStyleRTTI.rst
parent868d4470cdfa9472353ea2a49a6c456ddae9c95b (diff)
parentc204410d6bc435e7cb8ea768759a54135e8e92b5 (diff)
Updating branches/google/testing to r177703testing
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/testing@177985 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``