20
20
#include " swift/Basic/TypeID.h"
21
21
#include " llvm/ADT/DenseMapInfo.h"
22
22
#include " llvm/ADT/Hashing.h"
23
+ #include " llvm/ADT/IntrusiveRefCntPtr.h"
23
24
#include < string>
24
25
25
26
namespace llvm {
@@ -49,8 +50,14 @@ class DiagnosticEngine;
49
50
// / void noteCycleStep(DiagnosticEngine &diags) const;
50
51
// /
51
52
class AnyRequest {
53
+ friend llvm::DenseMapInfo<swift::AnyRequest>;
54
+
55
+ static hash_code hashForHolder (uint64_t typeID, hash_code requestHash) {
56
+ return hash_combine (hash_value (typeID), requestHash);
57
+ }
58
+
52
59
// / Abstract base class used to hold the specific request kind.
53
- class HolderBase {
60
+ class HolderBase : public llvm ::RefCountedBase<HolderBase> {
54
61
public:
55
62
// / The type ID of the request being stored.
56
63
const uint64_t typeID;
@@ -61,7 +68,7 @@ class AnyRequest {
61
68
protected:
62
69
// / Initialize base with type ID and hash code.
63
70
HolderBase (uint64_t typeID, hash_code hash)
64
- : typeID(typeID), hash(hash_combine(hash_value( typeID) , hash)) { }
71
+ : typeID(typeID), hash(AnyRequest::hashForHolder( typeID, hash)) { }
65
72
66
73
public:
67
74
virtual ~HolderBase ();
@@ -128,7 +135,7 @@ class AnyRequest {
128
135
} storageKind = StorageKind::Normal;
129
136
130
137
// / The data stored in this value.
131
- std::shared_ptr <HolderBase> stored;
138
+ llvm::IntrusiveRefCntPtr <HolderBase> stored;
132
139
133
140
AnyRequest (StorageKind storageKind) : storageKind(storageKind) {
134
141
assert (storageKind != StorageKind::Normal);
@@ -159,17 +166,18 @@ class AnyRequest {
159
166
160
167
// / Construct a new instance with the given value.
161
168
template <typename T>
162
- AnyRequest (T&& value) : storageKind(StorageKind::Normal) {
169
+ explicit AnyRequest (T&& value) : storageKind(StorageKind::Normal) {
163
170
using ValueType =
164
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
165
- stored.reset (new Holder<ValueType>(std::forward<T>(value)));
171
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
172
+ stored = llvm::IntrusiveRefCntPtr<HolderBase>(
173
+ new Holder<ValueType>(std::forward<T>(value)));
166
174
}
167
175
168
176
// / Cast to a specific (known) type.
169
177
template <typename Request>
170
178
const Request &castTo () const {
171
179
assert (stored->typeID == TypeID<Request>::value && " wrong type in cast" );
172
- return static_cast <const Holder<Request> *>(stored.get ())->value ;
180
+ return static_cast <const Holder<Request> *>(stored.get ())->request ;
173
181
}
174
182
175
183
// / Try casting to a specific (known) type, returning \c nullptr on
@@ -179,7 +187,7 @@ class AnyRequest {
179
187
if (stored->typeID != TypeID<Request>::value)
180
188
return nullptr ;
181
189
182
- return &static_cast <const Holder<Request> *>(stored.get ())->value ;
190
+ return &static_cast <const Holder<Request> *>(stored.get ())->request ;
183
191
}
184
192
185
193
// / Diagnose a cycle detected for this request.
@@ -248,10 +256,25 @@ namespace llvm {
248
256
static unsigned getHashValue (const swift::AnyRequest &request) {
249
257
return hash_value (request);
250
258
}
259
+ template <typename Request>
260
+ static unsigned getHashValue (const Request &request) {
261
+ return swift::AnyRequest::hashForHolder (swift::TypeID<Request>::value,
262
+ hash_value (request));
263
+ }
251
264
static bool isEqual (const swift::AnyRequest &lhs,
252
265
const swift::AnyRequest &rhs) {
253
266
return lhs == rhs;
254
267
}
268
+ template <typename Request>
269
+ static bool isEqual (const Request &lhs,
270
+ const swift::AnyRequest &rhs) {
271
+ if (rhs == getEmptyKey () || rhs == getTombstoneKey ())
272
+ return false ;
273
+ const Request *rhsRequest = rhs.getAs <Request>();
274
+ if (!rhsRequest)
275
+ return false ;
276
+ return lhs == *rhsRequest;
277
+ }
255
278
};
256
279
257
280
} // end namespace llvm
0 commit comments