|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|