@@ -255,10 +255,14 @@ class alignas(1 << TypeAlignInBits) TypeBase {
255
255
TypeBase (const TypeBase&) = delete ;
256
256
void operator =(const TypeBase&) = delete ;
257
257
258
- // / CanonicalType - This field is always set to the ASTContext for canonical
259
- // / types, and is otherwise lazily populated by ASTContext when the canonical
260
- // / form of a non-canonical type is requested.
261
- llvm::PointerUnion<TypeBase *, const ASTContext *> CanonicalType;
258
+ // / This union contains to the ASTContext for canonical types, and is
259
+ // / otherwise lazily populated by ASTContext when the canonical form of a
260
+ // / non-canonical type is requested. The disposition of the union is stored
261
+ // / outside of the union for performance. See Bits.TypeBase.IsCanonical.
262
+ union {
263
+ CanType CanonicalType;
264
+ const ASTContext *Context;
265
+ };
262
266
263
267
// / Returns true if the given type is a sugared type.
264
268
// /
@@ -275,11 +279,14 @@ class alignas(1 << TypeAlignInBits) TypeBase {
275
279
union { uint64_t OpaqueBits;
276
280
277
281
SWIFT_INLINE_BITFIELD_BASE (TypeBase, bitmax (NumTypeKindBits,8 ) +
278
- RecursiveTypeProperties::BitWidth,
282
+ RecursiveTypeProperties::BitWidth + 1 ,
279
283
// / Kind - The discriminator that indicates what subclass of type this is.
280
284
Kind : bitmax (NumTypeKindBits,8 ),
281
285
282
- Properties : RecursiveTypeProperties::BitWidth
286
+ Properties : RecursiveTypeProperties::BitWidth,
287
+
288
+ // / Whether this type is canonical or not.
289
+ IsCanonical : 1
283
290
);
284
291
285
292
SWIFT_INLINE_BITFIELD (ErrorType, TypeBase, 1 ,
@@ -384,12 +391,15 @@ class alignas(1 << TypeAlignInBits) TypeBase {
384
391
protected:
385
392
TypeBase (TypeKind kind, const ASTContext *CanTypeCtx,
386
393
RecursiveTypeProperties properties)
387
- : CanonicalType ((TypeBase*) nullptr ) {
394
+ : Context ( nullptr ) {
388
395
Bits.OpaqueBits = 0 ;
389
396
Bits.TypeBase .Kind = static_cast <unsigned >(kind);
397
+ Bits.TypeBase .IsCanonical = false ;
390
398
// If this type is canonical, switch the CanonicalType union to ASTContext.
391
- if (CanTypeCtx)
392
- CanonicalType = CanTypeCtx;
399
+ if (CanTypeCtx) {
400
+ Bits.TypeBase .IsCanonical = true ;
401
+ Context = CanTypeCtx;
402
+ }
393
403
setRecursiveProperties (properties);
394
404
}
395
405
@@ -403,7 +413,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
403
413
TypeKind getKind () const { return static_cast <TypeKind>(Bits.TypeBase .Kind ); }
404
414
405
415
// / isCanonical - Return true if this is a canonical type.
406
- bool isCanonical () const { return CanonicalType. is < const ASTContext *>() ; }
416
+ bool isCanonical () const { return Bits. TypeBase . IsCanonical ; }
407
417
408
418
// / hasCanonicalTypeComputed - Return true if we've already computed a
409
419
// / canonical version of this type.
@@ -419,7 +429,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
419
429
if (isCanonical ())
420
430
return CanType (const_cast <TypeBase*>(this ));
421
431
if (hasCanonicalTypeComputed ())
422
- return CanType ( CanonicalType. get <TypeBase*>()) ;
432
+ return CanonicalType;
423
433
return const_cast <TypeBase*>(this )->computeCanonicalType ();
424
434
}
425
435
@@ -434,11 +444,10 @@ class alignas(1 << TypeAlignInBits) TypeBase {
434
444
// / getASTContext - Return the ASTContext that this type belongs to.
435
445
ASTContext &getASTContext () {
436
446
// If this type is canonical, it has the ASTContext in it.
437
- if (CanonicalType. is < const ASTContext *> ())
438
- return const_cast <ASTContext&>(*CanonicalType. get < const ASTContext *>() );
447
+ if (isCanonical ())
448
+ return * const_cast <ASTContext*>(Context );
439
449
// If not, canonicalize it to get the Context.
440
- return const_cast <ASTContext&>(*getCanonicalType ()->
441
- CanonicalType.get <const ASTContext *>());
450
+ return *const_cast <ASTContext*>(getCanonicalType ()->Context );
442
451
}
443
452
444
453
// / isEqual - Return true if these two types are equal, ignoring sugar.
@@ -5262,7 +5271,13 @@ inline CanType CanType::getWithoutSpecifierTypeImpl(CanType type) {
5262
5271
inline CanType CanType::getNominalParent () const {
5263
5272
return cast<NominalOrBoundGenericNominalType>(*this ).getParent ();
5264
5273
}
5265
-
5274
+
5275
+ inline bool CanType::isActuallyCanonicalOrNull () const {
5276
+ return getPointer () == nullptr ||
5277
+ getPointer () == llvm::DenseMapInfo<TypeBase *>::getTombstoneKey () ||
5278
+ getPointer ()->isCanonical ();
5279
+ }
5280
+
5266
5281
inline Type TupleTypeElt::getVarargBaseTy () const {
5267
5282
TypeBase *T = getType ().getPointer ();
5268
5283
if (auto *AT = dyn_cast<ArraySliceType>(T))
0 commit comments