[llvm/docs] Add advanced RTTI techniques to HowToSetUpLLVMStyleRTTI (#181863)

The `HowToSetUpLLVMStyleRTTI.rst` document contained a TODO requesting
documentation for advanced RTTI usage, such as the `isa_impl` and
`simplify_type` templates. This patch resolves and removes that TODO by
adding the relevant usage introductions for `simplify_type`.

Since `isa_impl` will be moved to `namespace detail` in the future we
are not including it in the documentation.

CC: @nikic @zwuis

Signed-off-by: Lidong Yan <yldhome2d2@gmail.com>
This commit is contained in:
Lidong Yan 2026-02-26 23:46:10 +08:00 committed by GitHub
parent 46aae01188
commit bbaf723d86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -391,13 +391,6 @@ is in ``bool DeclContext::classof(const Decl *)``, which asks the question
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
==============
@ -487,6 +480,46 @@ 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!
Enabling isa/cast/dyn_cast for Handle Types by Specializing ``simplify_type``
--------------------------------------------------------------------------------
It is common to require pointer handle types like smart pointers or iterators. Yet, since the
``classof`` method is only implemented for the underlying types, developers must manually unwrap
them into raw pointers prior to invoking ``isa``, ``cast``, or ``dyn_cast``.
To avoid this boilerplate, you can specialize the ``simplify_type`` template for your handle type.
For example, if you have an iterator class for ``Shape`` called ``ShapeIterator``, you can specialize
``simplify_type`` like so:
.. code-block:: c++
class ShapeIterator {
public:
ShapeIterator(Shape *ptr) : ptr(ptr) {}
Shape *get() const { return ptr; }
private:
Shape *ptr;
};
template <>
struct simplify_type<ShapeIterator> {
using SimpleType = Shape *;
static SimpleType getSimplifiedValue(const ShapeIterator &I) {
return I.get();
}
};
By doing this, you can now use ``isa``, ``cast``, and ``dyn_cast`` directly on ``ShapeIterator`` objects
without having to manually call ``get()`` on them. For example:
.. code-block:: c++
ShapeIterator it = ...;
/* if (Square *S = dyn_cast<Square>(it.get())) */
if (Square *S = dyn_cast<Square>(it)) {
/* do something with S ... */
}
Value to value casting
----------------------
In this case, we have a struct that is what we call 'nullable' - i.e. it is