Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:30

0001 //===-- llvm/Support/ExtensibleRTTI.h - ExtensibleRTTI support --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // \file
0010 //
0011 // Defines an extensible RTTI mechanism designed to work with Casting.h.
0012 //
0013 // Extensible RTTI differs from LLVM's primary RTTI mechanism (see
0014 // llvm.org/docs/HowToSetUpLLVMStyleRTTI.html) by supporting open type
0015 // hierarchies, where new types can be added from outside libraries without
0016 // needing to change existing code. LLVM's primary RTTI mechanism should be
0017 // preferred where possible, but where open hierarchies are needed this system
0018 // can be used.
0019 //
0020 // The RTTIRoot class defines methods for comparing type ids. Implementations
0021 // of these methods can be injected into new classes using the RTTIExtends
0022 // class template.
0023 //
0024 // E.g.
0025 //
0026 //   @code{.cpp}
0027 //   class MyBaseClass : public RTTIExtends<MyBaseClass, RTTIRoot> {
0028 //   public:
0029 //     static char ID;
0030 //     virtual void foo() = 0;
0031 //   };
0032 //
0033 //   class MyDerivedClass1 : public RTTIExtends<MyDerivedClass1, MyBaseClass> {
0034 //   public:
0035 //     static char ID;
0036 //     void foo() override {}
0037 //   };
0038 //
0039 //   class MyDerivedClass2 : public RTTIExtends<MyDerivedClass2, MyBaseClass> {
0040 //   public:
0041 //     static char ID;
0042 //     void foo() override {}
0043 //   };
0044 //
0045 //   char MyBaseClass::ID = 0;
0046 //   char MyDerivedClass1::ID = 0;
0047 //   char MyDerivedClass2:: ID = 0;
0048 //
0049 //   void fn() {
0050 //     std::unique_ptr<MyBaseClass> B = llvm::make_unique<MyDerivedClass1>();
0051 //     llvm::outs() << isa<MyBaseClass>(B) << "\n"; // Outputs "1".
0052 //     llvm::outs() << isa<MyDerivedClass1>(B) << "\n"; // Outputs "1".
0053 //     llvm::outs() << isa<MyDerivedClass2>(B) << "\n"; // Outputs "0'.
0054 //   }
0055 //
0056 //   @endcode
0057 //
0058 //===----------------------------------------------------------------------===//
0059 
0060 #ifndef LLVM_SUPPORT_EXTENSIBLERTTI_H
0061 #define LLVM_SUPPORT_EXTENSIBLERTTI_H
0062 
0063 namespace llvm {
0064 
0065 /// Base class for the extensible RTTI hierarchy.
0066 ///
0067 /// This class defines virtual methods, dynamicClassID and isA, that enable
0068 /// type comparisons.
0069 class RTTIRoot {
0070 public:
0071   virtual ~RTTIRoot() = default;
0072 
0073   /// Returns the class ID for this type.
0074   static const void *classID() { return &ID; }
0075 
0076   /// Returns the class ID for the dynamic type of this RTTIRoot instance.
0077   virtual const void *dynamicClassID() const = 0;
0078 
0079   /// Returns true if this class's ID matches the given class ID.
0080   virtual bool isA(const void *const ClassID) const {
0081     return ClassID == classID();
0082   }
0083 
0084 private:
0085   virtual void anchor();
0086 
0087   static char ID;
0088 };
0089 
0090 /// Inheritance utility for extensible RTTI.
0091 ///
0092 /// Multiple inheritance is supported, but RTTIExtends only inherits
0093 /// constructors from the first base class. All subsequent bases will be
0094 /// default constructed. Virtual and non-public inheritance are not supported.
0095 ///
0096 /// RTTIExtents uses CRTP so the first template argument to RTTIExtends is the
0097 /// newly introduced type, and the *second and later* arguments are the parent
0098 /// classes.
0099 ///
0100 /// @code{.cpp}
0101 /// class MyType : public RTTIExtends<MyType, RTTIRoot> {
0102 /// public:
0103 ///   static char ID;
0104 /// };
0105 ///
0106 /// class MyDerivedType : public RTTIExtends<MyDerivedType, MyType> {
0107 /// public:
0108 ///   static char ID;
0109 /// };
0110 ///
0111 /// class MyOtherType : public RTTIExtends<MyOtherType, MyType> {
0112 /// public:
0113 ///   static char ID;
0114 /// };
0115 ///
0116 /// class MyMultipleInheritanceType
0117 ///   : public RTTIExtends<MyMultipleInheritanceType,
0118 ///                        MyDerivedType, MyOtherType> {
0119 /// public:
0120 ///   static char ID;
0121 /// };
0122 ///
0123 /// @endcode
0124 ///
0125 template <typename ThisT, typename ParentT, typename... ParentTs>
0126 class RTTIExtends : public ParentT, public ParentTs... {
0127 public:
0128   // Inherit constructors from the first Parent.
0129   using ParentT::ParentT;
0130 
0131   static const void *classID() { return &ThisT::ID; }
0132 
0133   const void *dynamicClassID() const override { return &ThisT::ID; }
0134 
0135   /// Check whether this instance is a subclass of QueryT.
0136   template <typename QueryT> bool isA() const { return isA(QueryT::classID()); }
0137 
0138   bool isA(const void *const ClassID) const override {
0139     return ClassID == classID() || ParentT::isA(ClassID) ||
0140            (ParentTs::isA(ClassID) || ...);
0141   }
0142 
0143   template <typename T> static bool classof(const T *R) {
0144     return R->template isA<ThisT>();
0145   }
0146 };
0147 
0148 } // end namespace llvm
0149 
0150 #endif // LLVM_SUPPORT_EXTENSIBLERTTI_H