22
22
#include " swift/AST/SubstitutionList.h"
23
23
#include " swift/AST/Type.h"
24
24
#include " llvm/ADT/ArrayRef.h"
25
+ #include " llvm/ADT/DenseMapInfo.h"
25
26
#include " llvm/ADT/FoldingSet.h"
26
27
#include " llvm/ADT/Optional.h"
27
28
#include " llvm/Support/TrailingObjects.h"
@@ -154,25 +155,10 @@ class SubstitutionMap {
154
155
// / signature nor any replacement types/conformances.
155
156
Storage *storage = nullptr ;
156
157
157
- // / Retrieve the array of replacement types, which line up with the
158
- // / generic parameters.
159
- // /
160
- // / Note that the types may be null, for cases where the generic parameter
161
- // / is concrete but hasn't been queried yet.
162
- ArrayRef<Type> getReplacementTypes () const {
163
- return storage ? storage->getReplacementTypes () : ArrayRef<Type>();
164
- }
165
-
166
158
MutableArrayRef<Type> getReplacementTypes () {
167
159
return storage ? storage->getReplacementTypes () : MutableArrayRef<Type>();
168
160
}
169
161
170
- // / Retrieve the array of protocol conformances, which line up with the
171
- // / requirements of the generic signature.
172
- ArrayRef<ProtocolConformanceRef> getConformances () const {
173
- return storage ? storage->getConformances ()
174
- : ArrayRef<ProtocolConformanceRef>();
175
- }
176
162
MutableArrayRef<ProtocolConformanceRef> getConformances () {
177
163
return storage ? storage->getConformances ()
178
164
: MutableArrayRef<ProtocolConformanceRef>();
@@ -185,10 +171,21 @@ class SubstitutionMap {
185
171
ArrayRef<ProtocolConformanceRef> conformances)
186
172
: storage(Storage::get(genericSig, replacementTypes, conformances)) { }
187
173
174
+ explicit SubstitutionMap (Storage *storage) : storage(storage) { }
175
+
188
176
public:
189
177
// / Build an empty substitution map.
190
178
SubstitutionMap () { }
191
179
180
+ // / Build an interface type substitution map for the given generic
181
+ // / signature and a vector of Substitutions that correspond to the
182
+ // / requirements of this generic signature.
183
+ static SubstitutionMap get (GenericSignature *genericSig,
184
+ ArrayRef<Type> replacementTypes,
185
+ ArrayRef<ProtocolConformanceRef> conformances) {
186
+ return SubstitutionMap (genericSig, replacementTypes, conformances);
187
+ }
188
+
192
189
// / Build an interface type substitution map for the given generic
193
190
// / signature and a vector of Substitutions that correspond to the
194
191
// / requirements of this generic signature.
@@ -207,13 +204,32 @@ class SubstitutionMap {
207
204
return storage ? storage->getGenericSignature () : nullptr ;
208
205
}
209
206
207
+ // / Retrieve the array of protocol conformances, which line up with the
208
+ // / requirements of the generic signature.
209
+ ArrayRef<ProtocolConformanceRef> getConformances () const {
210
+ return storage ? storage->getConformances ()
211
+ : ArrayRef<ProtocolConformanceRef>();
212
+ }
213
+
210
214
// / Look up a conformance for the given type to the given protocol.
211
215
Optional<ProtocolConformanceRef>
212
216
lookupConformance (CanType type, ProtocolDecl *proto) const ;
213
217
214
218
// / Whether the substitution map is empty.
215
219
bool empty () const { return getGenericSignature () == nullptr ; }
216
220
221
+ // / Whether the substitution map is non-empty.
222
+ explicit operator bool () const { return !empty (); }
223
+
224
+ // / Retrieve the array of replacement types, which line up with the
225
+ // / generic parameters.
226
+ // /
227
+ // / Note that the types may be null, for cases where the generic parameter
228
+ // / is concrete but hasn't been queried yet.
229
+ ArrayRef<Type> getReplacementTypes () const {
230
+ return storage ? storage->getReplacementTypes () : ArrayRef<Type>();
231
+ }
232
+
217
233
// / Query whether any replacement types in the map contain archetypes.
218
234
bool hasArchetypes () const ;
219
235
@@ -292,6 +308,22 @@ class SubstitutionMap {
292
308
// / Profile the substitution map, for use with LLVM's FoldingSet.
293
309
void profile (llvm::FoldingSetNodeID &id) const ;
294
310
311
+ const void *getOpaqueValue () const { return storage; }
312
+
313
+ static SubstitutionMap getFromOpaqueValue (const void *ptr) {
314
+ return SubstitutionMap (const_cast <Storage *>((const Storage *)ptr));
315
+ }
316
+
317
+ static SubstitutionMap getEmptyKey () {
318
+ return SubstitutionMap (
319
+ (Storage *)llvm::DenseMapInfo<void *>::getEmptyKey ());
320
+ }
321
+
322
+ static SubstitutionMap getTombstoneKey () {
323
+ return SubstitutionMap (
324
+ (Storage *)llvm::DenseMapInfo<void *>::getTombstoneKey ());
325
+ }
326
+
295
327
private:
296
328
friend class GenericSignature ;
297
329
friend class GenericEnvironment ;
@@ -306,4 +338,37 @@ class SubstitutionMap {
306
338
307
339
} // end namespace swift
308
340
341
+ namespace llvm {
342
+ template <>
343
+ struct PointerLikeTypeTraits <swift::SubstitutionMap> {
344
+ static void *getAsVoidPointer (swift::SubstitutionMap map) {
345
+ return const_cast <void *>(map.getOpaqueValue ());
346
+ }
347
+ static swift::SubstitutionMap getFromVoidPointer (const void *ptr) {
348
+ return swift::SubstitutionMap::getFromOpaqueValue (ptr);
349
+ }
350
+
351
+ // / Note: Assuming storage is at leaste 4-byte aligned.
352
+ enum { NumLowBitsAvailable = 2 };
353
+ };
354
+
355
+ // Substitution maps hash just like pointers.
356
+ template <> struct DenseMapInfo <swift::SubstitutionMap> {
357
+ static swift::SubstitutionMap getEmptyKey () {
358
+ return swift::SubstitutionMap::getEmptyKey ();
359
+ }
360
+ static swift::SubstitutionMap getTombstoneKey () {
361
+ return swift::SubstitutionMap::getTombstoneKey ();
362
+ }
363
+ static unsigned getHashValue (swift::SubstitutionMap map) {
364
+ return DenseMapInfo<void *>::getHashValue (map.getOpaqueValue ());
365
+ }
366
+ static bool isEqual (swift::SubstitutionMap lhs,
367
+ swift::SubstitutionMap rhs) {
368
+ return lhs.getOpaqueValue () == rhs.getOpaqueValue ();
369
+ }
370
+ };
371
+
372
+ }
373
+
309
374
#endif
0 commit comments