Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/Support/ExtensibleRTTI.h - ExtensibleRTTI support --*- 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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // \file
  10. //
  11. // Defines an extensible RTTI mechanism designed to work with Casting.h.
  12. //
  13. // Extensible RTTI differs from LLVM's primary RTTI mechanism (see
  14. // llvm.org/docs/HowToSetUpLLVMStyleRTTI.html) by supporting open type
  15. // hierarchies, where new types can be added from outside libraries without
  16. // needing to change existing code. LLVM's primary RTTI mechanism should be
  17. // preferred where possible, but where open hierarchies are needed this system
  18. // can be used.
  19. //
  20. // The RTTIRoot class defines methods for comparing type ids. Implementations
  21. // of these methods can be injected into new classes using the RTTIExtends
  22. // class template.
  23. //
  24. // E.g.
  25. //
  26. //   @code{.cpp}
  27. //   class MyBaseClass : public RTTIExtends<MyBaseClass, RTTIRoot> {
  28. //   public:
  29. //     static char ID;
  30. //     virtual void foo() = 0;
  31. //   };
  32. //
  33. //   class MyDerivedClass1 : public RTTIExtends<MyDerivedClass1, MyBaseClass> {
  34. //   public:
  35. //     static char ID;
  36. //     void foo() override {}
  37. //   };
  38. //
  39. //   class MyDerivedClass2 : public RTTIExtends<MyDerivedClass2, MyBaseClass> {
  40. //   public:
  41. //     static char ID;
  42. //     void foo() override {}
  43. //   };
  44. //
  45. //   char MyBaseClass::ID = 0;
  46. //   char MyDerivedClass1::ID = 0;
  47. //   char MyDerivedClass2:: ID = 0;
  48. //
  49. //   void fn() {
  50. //     std::unique_ptr<MyBaseClass> B = llvm::make_unique<MyDerivedClass1>();
  51. //     llvm::outs() << isa<MyBaseClass>(B) << "\n"; // Outputs "1".
  52. //     llvm::outs() << isa<MyDerivedClass1>(B) << "\n"; // Outputs "1".
  53. //     llvm::outs() << isa<MyDerivedClass2>(B) << "\n"; // Outputs "0'.
  54. //   }
  55. //
  56. //   @endcode
  57. //
  58. //===----------------------------------------------------------------------===//
  59.  
  60. #ifndef LLVM_SUPPORT_EXTENSIBLERTTI_H
  61. #define LLVM_SUPPORT_EXTENSIBLERTTI_H
  62.  
  63. namespace llvm {
  64.  
  65. /// Base class for the extensible RTTI hierarchy.
  66. ///
  67. /// This class defines virtual methods, dynamicClassID and isA, that enable
  68. /// type comparisons.
  69. class RTTIRoot {
  70. public:
  71.   virtual ~RTTIRoot() = default;
  72.  
  73.   /// Returns the class ID for this type.
  74.   static const void *classID() { return &ID; }
  75.  
  76.   /// Returns the class ID for the dynamic type of this RTTIRoot instance.
  77.   virtual const void *dynamicClassID() const = 0;
  78.  
  79.   /// Returns true if this class's ID matches the given class ID.
  80.   virtual bool isA(const void *const ClassID) const {
  81.     return ClassID == classID();
  82.   }
  83.  
  84.   /// Check whether this instance is a subclass of QueryT.
  85.   template <typename QueryT>
  86.   bool isA() const { return isA(QueryT::classID()); }
  87.  
  88. private:
  89.   virtual void anchor();
  90.  
  91.   static char ID;
  92. };
  93.  
  94. /// Inheritance utility for extensible RTTI.
  95. ///
  96. /// Supports single inheritance only: A class can only have one
  97. /// ExtensibleRTTI-parent (i.e. a parent for which the isa<> test will work),
  98. /// though it can have many non-ExtensibleRTTI parents.
  99. ///
  100. /// RTTIExtents uses CRTP so the first template argument to RTTIExtends is the
  101. /// newly introduced type, and the *second* argument is the parent class.
  102. ///
  103. /// class MyType : public RTTIExtends<MyType, RTTIRoot> {
  104. /// public:
  105. ///   static char ID;
  106. /// };
  107. ///
  108. /// class MyDerivedType : public RTTIExtends<MyDerivedType, MyType> {
  109. /// public:
  110. ///   static char ID;
  111. /// };
  112. ///
  113. template <typename ThisT, typename ParentT>
  114. class RTTIExtends : public ParentT {
  115. public:
  116.   // Inherit constructors from ParentT.
  117.   using ParentT::ParentT;
  118.  
  119.   static const void *classID() { return &ThisT::ID; }
  120.  
  121.   const void *dynamicClassID() const override { return &ThisT::ID; }
  122.  
  123.   bool isA(const void *const ClassID) const override {
  124.     return ClassID == classID() || ParentT::isA(ClassID);
  125.   }
  126.  
  127.   static bool classof(const RTTIRoot *R) { return R->isA<ThisT>(); }
  128. };
  129.  
  130. } // end namespace llvm
  131.  
  132. #endif // LLVM_SUPPORT_EXTENSIBLERTTI_H
  133.