brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · d9d1814 Raw
146 lines · c
1//===------------- rtti.h - RTTI support for ORC RT -------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// \file10//11// Provides an extensible RTTI mechanism, that can be used regardless of whether12// the runtime is built with -frtti or not. This is predominantly used to13// support error handling.14//15// The RTTIRoot class defines methods for comparing type ids. Implementations16// of these methods can be injected into new classes using the RTTIExtends17// class template.18//19// E.g.20//21//   @code{.cpp}22//   class MyBaseClass : public RTTIExtends<MyBaseClass, RTTIRoot> {23//   public:24//     static char ID;25//     virtual void foo() = 0;26//   };27//28//   class MyDerivedClass1 : public RTTIExtends<MyDerivedClass1, MyBaseClass> {29//   public:30//     static char ID;31//     void foo() override {}32//   };33//34//   class MyDerivedClass2 : public RTTIExtends<MyDerivedClass2, MyBaseClass> {35//   public:36//     static char ID;37//     void foo() override {}38//   };39//40//   char MyBaseClass::ID = 0;41//   char MyDerivedClass1::ID = 0;42//   char MyDerivedClass2:: ID = 0;43//44//   void fn() {45//     std::unique_ptr<MyBaseClass> B = std::make_unique<MyDerivedClass1>();46//     outs() << isa<MyBaseClass>(B) << "\n"; // Outputs "1".47//     outs() << isa<MyDerivedClass1>(B) << "\n"; // Outputs "1".48//     outs() << isa<MyDerivedClass2>(B) << "\n"; // Outputs "0'.49//   }50//51//   @endcode52//53// Note:54//   This header was adapted from llvm/Support/ExtensibleRTTI.h, however the55// data structures are not shared and the code need not be kept in sync.56//57//===----------------------------------------------------------------------===//58 59#ifndef ORC_RT_RTTI_H60#define ORC_RT_RTTI_H61 62namespace orc_rt {63 64template <typename ThisT, typename ParentT> class RTTIExtends;65 66/// Base class for the extensible RTTI hierarchy.67///68/// This class defines virtual methods, dynamicClassID and isA, that enable69/// type comparisons.70class RTTIRoot {71public:72  virtual ~RTTIRoot() = default;73 74  /// Returns the class ID for this type.75  static const void *classID() { return &ID; }76 77  /// Returns the class ID for the dynamic type of this RTTIRoot instance.78  virtual const void *dynamicClassID() const = 0;79 80  /// Returns true if this class's ID matches the given class ID.81  virtual bool isA(const void *const ClassID) const {82    return ClassID == classID();83  }84 85  /// Check whether this instance is a subclass of QueryT.86  template <typename QueryT> bool isA() const { return isA(QueryT::classID()); }87 88  static bool classof(const RTTIRoot *R) { return R->isA<RTTIRoot>(); }89 90private:91  virtual void anchor();92 93  static char ID;94};95 96/// Inheritance utility for extensible RTTI.97///98/// Supports single inheritance only: A class can only have one99/// ExtensibleRTTI-parent (i.e. a parent for which the isa<> test will work),100/// though it can have many non-ExtensibleRTTI parents.101///102/// RTTIExtents uses CRTP so the first template argument to RTTIExtends is the103/// newly introduced type, and the *second* argument is the parent class.104///105/// class MyType : public RTTIExtends<MyType, RTTIRoot> {106/// public:107///   static char ID;108/// };109///110/// class MyDerivedType : public RTTIExtends<MyDerivedType, MyType> {111/// public:112///   static char ID;113/// };114///115template <typename ThisT, typename ParentT> class RTTIExtends : public ParentT {116public:117  // Inherit constructors and isA methods from ParentT.118  using ParentT::isA;119  using ParentT::ParentT;120 121  static char ID;122 123  static const void *classID() { return &ThisT::ID; }124 125  const void *dynamicClassID() const override { return &ThisT::ID; }126 127  bool isA(const void *const ClassID) const override {128    return ClassID == classID() || ParentT::isA(ClassID);129  }130 131  static bool classof(const RTTIRoot *R) { return R->isA<ThisT>(); }132};133 134template <typename ThisT, typename ParentT>135char RTTIExtends<ThisT, ParentT>::ID = 0;136 137/// Returns true if the given value is an instance of the template type138/// parameter.139template <typename To, typename From> bool isa(const From &Value) {140  return To::classof(&Value);141}142 143} // namespace orc_rt144 145#endif // ORC_RT_RTTI_H146