Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/orc/extensible_rtti.h
39566 views
1
//===------ extensible_rtti.h - Extensible RTTI 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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// \file
10
//
11
// Provides an extensible RTTI mechanism, that can be used regardless of whether
12
// the runtime is built with -frtti or not. This is predominantly used to
13
// support error handling.
14
//
15
// The RTTIRoot class defines methods for comparing type ids. Implementations
16
// of these methods can be injected into new classes using the RTTIExtends
17
// 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
// @endcode
52
//
53
// Note:
54
// This header was adapted from llvm/Support/ExtensibleRTTI.h, however the
55
// data structures are not shared and the code need not be kept in sync.
56
//
57
//===----------------------------------------------------------------------===//
58
59
#ifndef ORC_RT_EXTENSIBLE_RTTI_H
60
#define ORC_RT_EXTENSIBLE_RTTI_H
61
62
namespace __orc_rt {
63
64
template <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 enable
69
/// type comparisons.
70
class RTTIRoot {
71
public:
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
90
private:
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 one
99
/// 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 the
103
/// 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
///
115
template <typename ThisT, typename ParentT> class RTTIExtends : public ParentT {
116
public:
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
134
template <typename ThisT, typename ParentT>
135
char RTTIExtends<ThisT, ParentT>::ID = 0;
136
137
/// Returns true if the given value is an instance of the template type
138
/// parameter.
139
template <typename To, typename From> bool isa(const From &Value) {
140
return To::classof(&Value);
141
}
142
143
} // end namespace __orc_rt
144
145
#endif // ORC_RT_EXTENSIBLE_RTTI_H
146
147