@@ -36,6 +36,82 @@ enum class TypeRefKind {
36
36
#undef TYPEREF
37
37
};
38
38
39
+ // / An identifier containing the unique bit pattern made up of all of the
40
+ // / instance data needed to uniquely identify a TypeRef.
41
+ // /
42
+ // / This allows for uniquing (via Equal) and for keying into a dictionary for
43
+ // / caching.
44
+ // /
45
+ // / TypeRefs should be comparable by pointers, so if the TypeRefBuilder
46
+ // / gets a request to build a TypeRef with the same constructor arguments,
47
+ // / it should return the one already created with those arguments, not a fresh
48
+ // / copy. This allows for fast identity comparisons and substitutions, for
49
+ // / example. We use a similar strategy for Types in the full AST.
50
+ class TypeRefID {
51
+
52
+ std::vector<uint32_t > Bits;
53
+
54
+ public:
55
+ TypeRefID () = default ;
56
+
57
+ template <typename T>
58
+ void addPointer (const T *Pointer) {
59
+ auto Raw = reinterpret_cast <uintptr_t >(Pointer);
60
+ Bits.push_back ((uint32_t )Raw);
61
+ Bits.push_back (Raw >> 32 );
62
+ }
63
+
64
+ void addInteger (uint32_t Integer) {
65
+ Bits.push_back (Integer);
66
+ }
67
+
68
+ void addInteger (uint64_t Integer) {
69
+ Bits.push_back ((uint32_t )Integer);
70
+ Bits.push_back (Integer >> 32 );
71
+ }
72
+
73
+ void addString (const std::string &String) {
74
+ if (String.empty ()) {
75
+ Bits.push_back (0 );
76
+ } else {
77
+ size_t i = 0 ;
78
+ size_t chunks = String.size () / 4 ;
79
+ for (size_t chunk = 0 ; chunk < chunks; ++chunk, i+=4 ) {
80
+ uint32_t entry = ((uint32_t ) String[i]) +
81
+ (((uint32_t ) String[i+1 ]) << 8 ) +
82
+ (((uint32_t ) String[i+2 ]) << 16 ) +
83
+ (((uint32_t ) String[i+3 ]) << 24 );
84
+ Bits.push_back (entry);
85
+ }
86
+ for (; i < String.size (); ++i) {
87
+ Bits.push_back (String[i]);
88
+ }
89
+ }
90
+ }
91
+
92
+ struct Hash {
93
+ std::size_t operator ()(TypeRefID const &ID) const {
94
+ size_t Hash = 0 ;
95
+ std::hash<uint32_t > h;
96
+ for (auto x : ID.Bits ) {
97
+ Hash ^= h (x) + 0x9e3779b9 + (Hash << 6 ) + (Hash >> 2 );
98
+ }
99
+ return Hash;
100
+ }
101
+ };
102
+
103
+ struct Equal {
104
+ bool operator ()(const TypeRefID &lhs, const TypeRefID &rhs) const {
105
+ return lhs.Bits == rhs.Bits ;
106
+ }
107
+ };
108
+
109
+
110
+ bool operator ==(const TypeRefID &Other) {
111
+ return Bits == Other.Bits ;
112
+ }
113
+ };
114
+
39
115
class TypeRef ;
40
116
class TypeRefBuilder ;
41
117
using DepthAndIndex = std::pair<unsigned , unsigned >;
@@ -80,6 +156,12 @@ class BuiltinTypeRef final : public TypeRef {
80
156
return MangledName;
81
157
}
82
158
159
+ static TypeRefID Profile (const std::string &MangledName) {
160
+ TypeRefID ID;
161
+ ID.addString (MangledName);
162
+ return ID;
163
+ }
164
+
83
165
static bool classof (const TypeRef *TR) {
84
166
return TR->getKind () == TypeRefKind::Builtin;
85
167
}
@@ -107,6 +189,14 @@ class NominalTypeTrait {
107
189
}
108
190
109
191
unsigned getDepth () const ;
192
+
193
+ static TypeRefID Profile (const std::string &MangledName,
194
+ const TypeRef *Parent) {
195
+ TypeRefID ID;
196
+ ID.addString (MangledName);
197
+ ID.addPointer (Parent);
198
+ return ID;
199
+ }
110
200
};
111
201
112
202
class NominalTypeRef final : public TypeRef, public NominalTypeTrait {
@@ -122,6 +212,8 @@ class NominalTypeRef final : public TypeRef, public NominalTypeTrait {
122
212
return A.template makeTypeRef <NominalTypeRef>(MangledName, Parent);
123
213
}
124
214
215
+ using NominalTypeTrait::Profile;
216
+
125
217
static bool classof (const TypeRef *TR) {
126
218
return TR->getKind () == TypeRefKind::Nominal;
127
219
}
@@ -152,6 +244,17 @@ class BoundGenericTypeRef final : public TypeRef, public NominalTypeTrait {
152
244
return GenericParams;
153
245
}
154
246
247
+ static TypeRefID Profile (const std::string &MangledName,
248
+ const std::vector<const TypeRef *> &GenericParams,
249
+ const TypeRef *Parent) {
250
+ TypeRefID ID;
251
+ ID.addString (MangledName);
252
+ for (auto Param : GenericParams)
253
+ ID.addPointer (Param);
254
+ ID.addPointer (Parent);
255
+ return ID;
256
+ }
257
+
155
258
static bool classof (const TypeRef *TR) {
156
259
return TR->getKind () == TypeRefKind::BoundGeneric;
157
260
}
@@ -180,6 +283,16 @@ class TupleTypeRef final : public TypeRef {
180
283
return Variadic;
181
284
}
182
285
286
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Elements,
287
+ bool Variadic) {
288
+ TypeRefID ID;
289
+ for (auto Element : Elements)
290
+ ID.addPointer (Element);
291
+
292
+ ID.addInteger (static_cast <uint32_t >(Variadic));
293
+ return ID;
294
+ }
295
+
183
296
static bool classof (const TypeRef *TR) {
184
297
return TR->getKind () == TypeRefKind::Tuple;
185
298
}
@@ -216,6 +329,18 @@ class FunctionTypeRef final : public TypeRef {
216
329
return Flags;
217
330
}
218
331
332
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Arguments,
333
+ const TypeRef *Result,
334
+ FunctionTypeFlags Flags) {
335
+ TypeRefID ID;
336
+ for (auto Argument : Arguments) {
337
+ ID.addPointer (Argument);
338
+ }
339
+ ID.addPointer (Result);
340
+ ID.addInteger (static_cast <uint64_t >(Flags.getIntValue ()));
341
+ return ID;
342
+ }
343
+
219
344
static bool classof (const TypeRef *TR) {
220
345
return TR->getKind () == TypeRefKind::Function;
221
346
}
@@ -238,6 +363,12 @@ class ProtocolTypeRef final : public TypeRef {
238
363
return MangledName;
239
364
}
240
365
366
+ static TypeRefID Profile (const std::string &MangledName) {
367
+ TypeRefID ID;
368
+ ID.addString (MangledName);
369
+ return ID;
370
+ }
371
+
241
372
static bool classof (const TypeRef *TR) {
242
373
return TR->getKind () == TypeRefKind::Protocol;
243
374
}
@@ -267,6 +398,14 @@ class ProtocolCompositionTypeRef final : public TypeRef {
267
398
return Protocols;
268
399
}
269
400
401
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Protocols) {
402
+ TypeRefID ID;
403
+ for (auto Protocol : Protocols) {
404
+ ID.addPointer (Protocol);
405
+ }
406
+ return ID;
407
+ }
408
+
270
409
static bool classof (const TypeRef *TR) {
271
410
return TR->getKind () == TypeRefKind::ProtocolComposition;
272
411
}
@@ -296,6 +435,12 @@ class MetatypeTypeRef final : public TypeRef {
296
435
return InstanceType;
297
436
}
298
437
438
+ static TypeRefID Profile (const TypeRef *InstanceType) {
439
+ TypeRefID ID;
440
+ ID.addPointer (InstanceType);
441
+ return ID;
442
+ }
443
+
299
444
static bool classof (const TypeRef *TR) {
300
445
return TR->getKind () == TypeRefKind::Metatype;
301
446
}
@@ -318,6 +463,12 @@ class ExistentialMetatypeTypeRef final : public TypeRef {
318
463
return InstanceType;
319
464
}
320
465
466
+ static TypeRefID Profile (const TypeRef *InstanceType) {
467
+ TypeRefID ID;
468
+ ID.addPointer (InstanceType);
469
+ return ID;
470
+ }
471
+
321
472
static bool classof (const TypeRef *TR) {
322
473
return TR->getKind () == TypeRefKind::ExistentialMetatype;
323
474
}
@@ -345,6 +496,13 @@ class GenericTypeParameterTypeRef final : public TypeRef {
345
496
return Index;
346
497
}
347
498
499
+ static TypeRefID Profile (uint32_t Depth, uint32_t Index) {
500
+ TypeRefID ID;
501
+ ID.addInteger (Depth);
502
+ ID.addInteger (Index);
503
+ return ID;
504
+ }
505
+
348
506
static bool classof (const TypeRef *TR) {
349
507
return TR->getKind () == TypeRefKind::GenericTypeParameter;
350
508
}
@@ -381,21 +539,26 @@ class DependentMemberTypeRef final : public TypeRef {
381
539
return cast<ProtocolTypeRef>(Protocol);
382
540
}
383
541
542
+ static TypeRefID Profile (const std::string &Member, const TypeRef *Base,
543
+ const TypeRef *Protocol) {
544
+ TypeRefID ID;
545
+ ID.addString (Member);
546
+ ID.addPointer (Base);
547
+ ID.addPointer (Protocol);
548
+ return ID;
549
+ }
550
+
384
551
static bool classof (const TypeRef *TR) {
385
552
return TR->getKind () == TypeRefKind::DependentMember;
386
553
}
387
554
};
388
555
389
556
class ForeignClassTypeRef final : public TypeRef {
390
557
std::string Name;
391
- static const ForeignClassTypeRef *UnnamedSingleton;
392
558
public:
393
559
ForeignClassTypeRef (const std::string &Name)
394
560
: TypeRef(TypeRefKind::ForeignClass), Name(Name) {}
395
561
396
- static const ForeignClassTypeRef *getUnnamed ();
397
-
398
-
399
562
template <typename Allocator>
400
563
static ForeignClassTypeRef *create (Allocator &A,
401
564
const std::string &Name) {
@@ -406,6 +569,12 @@ class ForeignClassTypeRef final : public TypeRef {
406
569
return Name;
407
570
}
408
571
572
+ static TypeRefID Profile (const std::string &Name) {
573
+ TypeRefID ID;
574
+ ID.addString (Name);
575
+ return ID;
576
+ }
577
+
409
578
static bool classof (const TypeRef *TR) {
410
579
return TR->getKind () == TypeRefKind::ForeignClass;
411
580
}
@@ -429,6 +598,12 @@ class ObjCClassTypeRef final : public TypeRef {
429
598
return Name;
430
599
}
431
600
601
+ static TypeRefID Profile (const std::string &Name) {
602
+ TypeRefID ID;
603
+ ID.addString (Name);
604
+ return ID;
605
+ }
606
+
432
607
static bool classof (const TypeRef *TR) {
433
608
return TR->getKind () == TypeRefKind::ObjCClass;
434
609
}
@@ -441,6 +616,10 @@ class OpaqueTypeRef final : public TypeRef {
441
616
442
617
static const OpaqueTypeRef *get ();
443
618
619
+ static TypeRefID Profile () {
620
+ return TypeRefID ();
621
+ }
622
+
444
623
static bool classof (const TypeRef *TR) {
445
624
return TR->getKind () == TypeRefKind::Opaque;
446
625
}
@@ -457,6 +636,12 @@ class ReferenceStorageTypeRef : public TypeRef {
457
636
const TypeRef *getType () const {
458
637
return Type;
459
638
}
639
+
640
+ static TypeRefID Profile (const TypeRef *Type) {
641
+ TypeRefID ID;
642
+ ID.addPointer (Type);
643
+ return ID;
644
+ }
460
645
};
461
646
462
647
class UnownedStorageTypeRef final : public ReferenceStorageTypeRef {
@@ -470,6 +655,8 @@ class UnownedStorageTypeRef final : public ReferenceStorageTypeRef {
470
655
return A.template makeTypeRef <UnownedStorageTypeRef>(Type);
471
656
}
472
657
658
+ using ReferenceStorageTypeRef::Profile;
659
+
473
660
static bool classof (const TypeRef *TR) {
474
661
return TR->getKind () == TypeRefKind::UnownedStorage;
475
662
}
@@ -486,6 +673,8 @@ class WeakStorageTypeRef final : public ReferenceStorageTypeRef {
486
673
return A.template makeTypeRef <WeakStorageTypeRef>(Type);
487
674
}
488
675
676
+ using ReferenceStorageTypeRef::Profile;
677
+
489
678
static bool classof (const TypeRef *TR) {
490
679
return TR->getKind () == TypeRefKind::WeakStorage;
491
680
}
@@ -502,6 +691,8 @@ class UnmanagedStorageTypeRef final : public ReferenceStorageTypeRef {
502
691
return A.template makeTypeRef <UnmanagedStorageTypeRef>(Type);
503
692
}
504
693
694
+ using ReferenceStorageTypeRef::Profile;
695
+
505
696
static bool classof (const TypeRef *TR) {
506
697
return TR->getKind () == TypeRefKind::UnmanagedStorage;
507
698
}
0 commit comments