@@ -36,6 +36,84 @@ 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 <uint32_t *>(&Pointer);
60
+ Bits.push_back (Raw[0 ]);
61
+ if (sizeof (const T *) > 4 ) {
62
+ Bits.push_back (Raw[1 ]);
63
+ }
64
+ }
65
+
66
+ void addInteger (uint32_t Integer) {
67
+ Bits.push_back (Integer);
68
+ }
69
+
70
+ void addInteger (uint64_t Integer) {
71
+ Bits.push_back ((uint32_t )Integer);
72
+ Bits.push_back (Integer >> 32 );
73
+ }
74
+
75
+ void addString (const std::string &String) {
76
+ if (String.empty ()) {
77
+ Bits.push_back (0 );
78
+ } else {
79
+ size_t i = 0 ;
80
+ size_t chunks = String.size () / 4 ;
81
+ for (size_t chunk = 0 ; chunk < chunks; ++chunk, i+=4 ) {
82
+ uint32_t entry = ((uint32_t ) String[i]) +
83
+ (((uint32_t ) String[i+1 ]) << 8 ) +
84
+ (((uint32_t ) String[i+2 ]) << 16 ) +
85
+ (((uint32_t ) String[i+3 ]) << 24 );
86
+ Bits.push_back (entry);
87
+ }
88
+ for (; i < String.size (); ++i) {
89
+ Bits.push_back (String[i]);
90
+ }
91
+ }
92
+ }
93
+
94
+ struct Hash {
95
+ std::size_t operator ()(TypeRefID const &ID) const {
96
+ size_t Hash = 0 ;
97
+ std::hash<uint32_t > h;
98
+ for (auto x : ID.Bits ) {
99
+ Hash ^= h (x) + 0x9e3779b9 + (Hash << 6 ) + (Hash >> 2 );
100
+ }
101
+ return Hash;
102
+ }
103
+ };
104
+
105
+ struct Equal {
106
+ bool operator ()(const TypeRefID &lhs, const TypeRefID &rhs) const {
107
+ return lhs.Bits == rhs.Bits ;
108
+ }
109
+ };
110
+
111
+
112
+ bool operator ==(const TypeRefID &Other) {
113
+ return Bits == Other.Bits ;
114
+ }
115
+ };
116
+
39
117
class TypeRef ;
40
118
class TypeRefBuilder ;
41
119
using DepthAndIndex = std::pair<unsigned , unsigned >;
@@ -80,6 +158,12 @@ class BuiltinTypeRef final : public TypeRef {
80
158
return MangledName;
81
159
}
82
160
161
+ static TypeRefID Profile (const std::string &MangledName) {
162
+ TypeRefID ID;
163
+ ID.addString (MangledName);
164
+ return ID;
165
+ }
166
+
83
167
static bool classof (const TypeRef *TR) {
84
168
return TR->getKind () == TypeRefKind::Builtin;
85
169
}
@@ -107,6 +191,14 @@ class NominalTypeTrait {
107
191
}
108
192
109
193
unsigned getDepth () const ;
194
+
195
+ static TypeRefID Profile (const std::string &MangledName,
196
+ const TypeRef *Parent) {
197
+ TypeRefID ID;
198
+ ID.addString (MangledName);
199
+ ID.addPointer (Parent);
200
+ return ID;
201
+ }
110
202
};
111
203
112
204
class NominalTypeRef final : public TypeRef, public NominalTypeTrait {
@@ -122,6 +214,8 @@ class NominalTypeRef final : public TypeRef, public NominalTypeTrait {
122
214
return A.template makeTypeRef <NominalTypeRef>(MangledName, Parent);
123
215
}
124
216
217
+ using NominalTypeTrait::Profile;
218
+
125
219
static bool classof (const TypeRef *TR) {
126
220
return TR->getKind () == TypeRefKind::Nominal;
127
221
}
@@ -152,6 +246,17 @@ class BoundGenericTypeRef final : public TypeRef, public NominalTypeTrait {
152
246
return GenericParams;
153
247
}
154
248
249
+ static TypeRefID Profile (const std::string &MangledName,
250
+ const std::vector<const TypeRef *> &GenericParams,
251
+ const TypeRef *Parent) {
252
+ TypeRefID ID;
253
+ ID.addString (MangledName);
254
+ for (auto Param : GenericParams)
255
+ ID.addPointer (Param);
256
+ ID.addPointer (Parent);
257
+ return ID;
258
+ }
259
+
155
260
static bool classof (const TypeRef *TR) {
156
261
return TR->getKind () == TypeRefKind::BoundGeneric;
157
262
}
@@ -180,6 +285,16 @@ class TupleTypeRef final : public TypeRef {
180
285
return Variadic;
181
286
}
182
287
288
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Elements,
289
+ bool Variadic) {
290
+ TypeRefID ID;
291
+ for (auto Element : Elements)
292
+ ID.addPointer (Element);
293
+
294
+ ID.addInteger (static_cast <uint32_t >(Variadic));
295
+ return ID;
296
+ }
297
+
183
298
static bool classof (const TypeRef *TR) {
184
299
return TR->getKind () == TypeRefKind::Tuple;
185
300
}
@@ -216,6 +331,18 @@ class FunctionTypeRef final : public TypeRef {
216
331
return Flags;
217
332
}
218
333
334
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Arguments,
335
+ const TypeRef *Result,
336
+ FunctionTypeFlags Flags) {
337
+ TypeRefID ID;
338
+ for (auto Argument : Arguments) {
339
+ ID.addPointer (Argument);
340
+ }
341
+ ID.addPointer (Result);
342
+ ID.addInteger (static_cast <uint64_t >(Flags.getIntValue ()));
343
+ return ID;
344
+ }
345
+
219
346
static bool classof (const TypeRef *TR) {
220
347
return TR->getKind () == TypeRefKind::Function;
221
348
}
@@ -238,6 +365,12 @@ class ProtocolTypeRef final : public TypeRef {
238
365
return MangledName;
239
366
}
240
367
368
+ static TypeRefID Profile (const std::string &MangledName) {
369
+ TypeRefID ID;
370
+ ID.addString (MangledName);
371
+ return ID;
372
+ }
373
+
241
374
static bool classof (const TypeRef *TR) {
242
375
return TR->getKind () == TypeRefKind::Protocol;
243
376
}
@@ -267,6 +400,14 @@ class ProtocolCompositionTypeRef final : public TypeRef {
267
400
return Protocols;
268
401
}
269
402
403
+ static TypeRefID Profile (const std::vector<const TypeRef *> &Protocols) {
404
+ TypeRefID ID;
405
+ for (auto Protocol : Protocols) {
406
+ ID.addPointer (Protocol);
407
+ }
408
+ return ID;
409
+ }
410
+
270
411
static bool classof (const TypeRef *TR) {
271
412
return TR->getKind () == TypeRefKind::ProtocolComposition;
272
413
}
@@ -296,6 +437,12 @@ class MetatypeTypeRef final : public TypeRef {
296
437
return InstanceType;
297
438
}
298
439
440
+ static TypeRefID Profile (const TypeRef *InstanceType) {
441
+ TypeRefID ID;
442
+ ID.addPointer (InstanceType);
443
+ return ID;
444
+ }
445
+
299
446
static bool classof (const TypeRef *TR) {
300
447
return TR->getKind () == TypeRefKind::Metatype;
301
448
}
@@ -318,6 +465,12 @@ class ExistentialMetatypeTypeRef final : public TypeRef {
318
465
return InstanceType;
319
466
}
320
467
468
+ static TypeRefID Profile (const TypeRef *InstanceType) {
469
+ TypeRefID ID;
470
+ ID.addPointer (InstanceType);
471
+ return ID;
472
+ }
473
+
321
474
static bool classof (const TypeRef *TR) {
322
475
return TR->getKind () == TypeRefKind::ExistentialMetatype;
323
476
}
@@ -345,6 +498,13 @@ class GenericTypeParameterTypeRef final : public TypeRef {
345
498
return Index;
346
499
}
347
500
501
+ static TypeRefID Profile (uint32_t Depth, uint32_t Index) {
502
+ TypeRefID ID;
503
+ ID.addInteger (Depth);
504
+ ID.addInteger (Index);
505
+ return ID;
506
+ }
507
+
348
508
static bool classof (const TypeRef *TR) {
349
509
return TR->getKind () == TypeRefKind::GenericTypeParameter;
350
510
}
@@ -381,21 +541,26 @@ class DependentMemberTypeRef final : public TypeRef {
381
541
return cast<ProtocolTypeRef>(Protocol);
382
542
}
383
543
544
+ static TypeRefID Profile (const std::string &Member, const TypeRef *Base,
545
+ const TypeRef *Protocol) {
546
+ TypeRefID ID;
547
+ ID.addString (Member);
548
+ ID.addPointer (Base);
549
+ ID.addPointer (Protocol);
550
+ return ID;
551
+ }
552
+
384
553
static bool classof (const TypeRef *TR) {
385
554
return TR->getKind () == TypeRefKind::DependentMember;
386
555
}
387
556
};
388
557
389
558
class ForeignClassTypeRef final : public TypeRef {
390
559
std::string Name;
391
- static const ForeignClassTypeRef *UnnamedSingleton;
392
560
public:
393
561
ForeignClassTypeRef (const std::string &Name)
394
562
: TypeRef(TypeRefKind::ForeignClass), Name(Name) {}
395
563
396
- static const ForeignClassTypeRef *getUnnamed ();
397
-
398
-
399
564
template <typename Allocator>
400
565
static ForeignClassTypeRef *create (Allocator &A,
401
566
const std::string &Name) {
@@ -406,6 +571,12 @@ class ForeignClassTypeRef final : public TypeRef {
406
571
return Name;
407
572
}
408
573
574
+ static TypeRefID Profile (const std::string &Name) {
575
+ TypeRefID ID;
576
+ ID.addString (Name);
577
+ return ID;
578
+ }
579
+
409
580
static bool classof (const TypeRef *TR) {
410
581
return TR->getKind () == TypeRefKind::ForeignClass;
411
582
}
@@ -429,6 +600,12 @@ class ObjCClassTypeRef final : public TypeRef {
429
600
return Name;
430
601
}
431
602
603
+ static TypeRefID Profile (const std::string &Name) {
604
+ TypeRefID ID;
605
+ ID.addString (Name);
606
+ return ID;
607
+ }
608
+
432
609
static bool classof (const TypeRef *TR) {
433
610
return TR->getKind () == TypeRefKind::ObjCClass;
434
611
}
@@ -441,6 +618,10 @@ class OpaqueTypeRef final : public TypeRef {
441
618
442
619
static const OpaqueTypeRef *get ();
443
620
621
+ static TypeRefID Profile () {
622
+ return TypeRefID ();
623
+ }
624
+
444
625
static bool classof (const TypeRef *TR) {
445
626
return TR->getKind () == TypeRefKind::Opaque;
446
627
}
@@ -457,6 +638,12 @@ class ReferenceStorageTypeRef : public TypeRef {
457
638
const TypeRef *getType () const {
458
639
return Type;
459
640
}
641
+
642
+ static TypeRefID Profile (const TypeRef *Type) {
643
+ TypeRefID ID;
644
+ ID.addPointer (Type);
645
+ return ID;
646
+ }
460
647
};
461
648
462
649
class UnownedStorageTypeRef final : public ReferenceStorageTypeRef {
@@ -470,6 +657,8 @@ class UnownedStorageTypeRef final : public ReferenceStorageTypeRef {
470
657
return A.template makeTypeRef <UnownedStorageTypeRef>(Type);
471
658
}
472
659
660
+ using ReferenceStorageTypeRef::Profile;
661
+
473
662
static bool classof (const TypeRef *TR) {
474
663
return TR->getKind () == TypeRefKind::UnownedStorage;
475
664
}
@@ -486,6 +675,8 @@ class WeakStorageTypeRef final : public ReferenceStorageTypeRef {
486
675
return A.template makeTypeRef <WeakStorageTypeRef>(Type);
487
676
}
488
677
678
+ using ReferenceStorageTypeRef::Profile;
679
+
489
680
static bool classof (const TypeRef *TR) {
490
681
return TR->getKind () == TypeRefKind::WeakStorage;
491
682
}
@@ -502,6 +693,8 @@ class UnmanagedStorageTypeRef final : public ReferenceStorageTypeRef {
502
693
return A.template makeTypeRef <UnmanagedStorageTypeRef>(Type);
503
694
}
504
695
696
+ using ReferenceStorageTypeRef::Profile;
697
+
505
698
static bool classof (const TypeRef *TR) {
506
699
return TR->getKind () == TypeRefKind::UnmanagedStorage;
507
700
}
0 commit comments