From bbaf723d863704017226b0f6fb4af26b779c0e89 Mon Sep 17 00:00:00 2001 From: Lidong Yan Date: Thu, 26 Feb 2026 23:46:10 +0800 Subject: [PATCH] [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 --- llvm/docs/HowToSetUpLLVMStyleRTTI.rst | 47 +++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/llvm/docs/HowToSetUpLLVMStyleRTTI.rst b/llvm/docs/HowToSetUpLLVMStyleRTTI.rst index 423f4d5ffc56..7cfdaa07c5e7 100644 --- a/llvm/docs/HowToSetUpLLVMStyleRTTI.rst +++ b/llvm/docs/HowToSetUpLLVMStyleRTTI.rst @@ -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 { + 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(it.get())) */ + if (Square *S = dyn_cast(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