Path: blob/main/contrib/llvm-project/compiler-rt/lib/orc/extensible_rtti.h
39566 views
//===------ extensible_rtti.h - Extensible RTTI for ORC RT ------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// \file9//10// Provides an extensible RTTI mechanism, that can be used regardless of whether11// the runtime is built with -frtti or not. This is predominantly used to12// support error handling.13//14// The RTTIRoot class defines methods for comparing type ids. Implementations15// of these methods can be injected into new classes using the RTTIExtends16// class template.17//18// E.g.19//20// @code{.cpp}21// class MyBaseClass : public RTTIExtends<MyBaseClass, RTTIRoot> {22// public:23// static char ID;24// virtual void foo() = 0;25// };26//27// class MyDerivedClass1 : public RTTIExtends<MyDerivedClass1, MyBaseClass> {28// public:29// static char ID;30// void foo() override {}31// };32//33// class MyDerivedClass2 : public RTTIExtends<MyDerivedClass2, MyBaseClass> {34// public:35// static char ID;36// void foo() override {}37// };38//39// char MyBaseClass::ID = 0;40// char MyDerivedClass1::ID = 0;41// char MyDerivedClass2:: ID = 0;42//43// void fn() {44// std::unique_ptr<MyBaseClass> B = std::make_unique<MyDerivedClass1>();45// outs() << isa<MyBaseClass>(B) << "\n"; // Outputs "1".46// outs() << isa<MyDerivedClass1>(B) << "\n"; // Outputs "1".47// outs() << isa<MyDerivedClass2>(B) << "\n"; // Outputs "0'.48// }49//50// @endcode51//52// Note:53// This header was adapted from llvm/Support/ExtensibleRTTI.h, however the54// data structures are not shared and the code need not be kept in sync.55//56//===----------------------------------------------------------------------===//5758#ifndef ORC_RT_EXTENSIBLE_RTTI_H59#define ORC_RT_EXTENSIBLE_RTTI_H6061namespace __orc_rt {6263template <typename ThisT, typename ParentT> class RTTIExtends;6465/// Base class for the extensible RTTI hierarchy.66///67/// This class defines virtual methods, dynamicClassID and isA, that enable68/// type comparisons.69class RTTIRoot {70public:71virtual ~RTTIRoot() = default;7273/// Returns the class ID for this type.74static const void *classID() { return &ID; }7576/// Returns the class ID for the dynamic type of this RTTIRoot instance.77virtual const void *dynamicClassID() const = 0;7879/// Returns true if this class's ID matches the given class ID.80virtual bool isA(const void *const ClassID) const {81return ClassID == classID();82}8384/// Check whether this instance is a subclass of QueryT.85template <typename QueryT> bool isA() const { return isA(QueryT::classID()); }8687static bool classof(const RTTIRoot *R) { return R->isA<RTTIRoot>(); }8889private:90virtual void anchor();9192static char ID;93};9495/// Inheritance utility for extensible RTTI.96///97/// Supports single inheritance only: A class can only have one98/// ExtensibleRTTI-parent (i.e. a parent for which the isa<> test will work),99/// though it can have many non-ExtensibleRTTI parents.100///101/// RTTIExtents uses CRTP so the first template argument to RTTIExtends is the102/// newly introduced type, and the *second* argument is the parent class.103///104/// class MyType : public RTTIExtends<MyType, RTTIRoot> {105/// public:106/// static char ID;107/// };108///109/// class MyDerivedType : public RTTIExtends<MyDerivedType, MyType> {110/// public:111/// static char ID;112/// };113///114template <typename ThisT, typename ParentT> class RTTIExtends : public ParentT {115public:116// Inherit constructors and isA methods from ParentT.117using ParentT::isA;118using ParentT::ParentT;119120static char ID;121122static const void *classID() { return &ThisT::ID; }123124const void *dynamicClassID() const override { return &ThisT::ID; }125126bool isA(const void *const ClassID) const override {127return ClassID == classID() || ParentT::isA(ClassID);128}129130static bool classof(const RTTIRoot *R) { return R->isA<ThisT>(); }131};132133template <typename ThisT, typename ParentT>134char RTTIExtends<ThisT, ParentT>::ID = 0;135136/// Returns true if the given value is an instance of the template type137/// parameter.138template <typename To, typename From> bool isa(const From &Value) {139return To::classof(&Value);140}141142} // end namespace __orc_rt143144#endif // ORC_RT_EXTENSIBLE_RTTI_H145146147