Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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