Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1556,10 +1556,7 @@ unsigned NumTypeArgs : 7; /// The number of protocols stored directly on this object type. - unsigned NumProtocols : 6; - - /// Whether this is a "kindof" type. - unsigned IsKindOf : 1; + unsigned NumProtocols : 7; }; class ReferenceTypeBitfields { @@ -5560,9 +5557,12 @@ /// Either a BuiltinType or an InterfaceType or sugar for either. QualType BaseType; - /// Cached superclass type. - mutable llvm::PointerIntPair - CachedSuperClassType; + using CachedSuperClassStorage = + llvm::PointerIntPair; + + /// Cached superclass type plus whether this type was written with '__kindof'. + mutable llvm::PointerIntPair + CachedSuperClassAndIsKindOf; QualType *getTypeArgStorage(); const QualType *getTypeArgStorage() const { @@ -5592,7 +5592,6 @@ BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumTypeArgs = 0; - ObjCObjectTypeBits.IsKindOf = 0; } void computeSuperClassTypeSlow() const; @@ -5658,7 +5657,9 @@ } /// Whether this is a "__kindof" type as written. - bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } + bool isKindOfTypeAsWritten() const { + return CachedSuperClassAndIsKindOf.getInt(); + } /// Whether this ia a "__kindof" type (semantically). bool isKindOfType() const; @@ -5670,11 +5671,12 @@ /// specialization of the superclass type. Produces a null type if /// there is no superclass. QualType getSuperClassType() const { - if (!CachedSuperClassType.getInt()) + if (!CachedSuperClassAndIsKindOf.getPointer().getInt()) computeSuperClassTypeSlow(); - assert(CachedSuperClassType.getInt() && "Superclass not set?"); - return QualType(CachedSuperClassType.getPointer(), 0); + assert(CachedSuperClassAndIsKindOf.getPointer().getInt() && + "Superclass not set?"); + return QualType(CachedSuperClassAndIsKindOf.getPointer().getPointer(), 0); } /// Strip off the Objective-C "kindof" type and (with it) any Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -621,7 +621,7 @@ Base->isVariablyModifiedType(), Base->containsUnexpandedParameterPack()), BaseType(Base) { - ObjCObjectTypeBits.IsKindOf = isKindOf; + CachedSuperClassAndIsKindOf.setInt(isKindOf); ObjCObjectTypeBits.NumTypeArgs = typeArgs.size(); assert(getTypeArgsAsWritten().size() == typeArgs.size() && @@ -1454,20 +1454,20 @@ // superclass type. ObjCInterfaceDecl *classDecl = getInterface(); if (!classDecl) { - CachedSuperClassType.setInt(true); + CachedSuperClassAndIsKindOf.setPointer({nullptr, true}); return; } // Extract the superclass type. const ObjCObjectType *superClassObjTy = classDecl->getSuperClassType(); if (!superClassObjTy) { - CachedSuperClassType.setInt(true); + CachedSuperClassAndIsKindOf.setPointer({nullptr, true}); return; } ObjCInterfaceDecl *superClassDecl = superClassObjTy->getInterface(); if (!superClassDecl) { - CachedSuperClassType.setInt(true); + CachedSuperClassAndIsKindOf.setPointer({nullptr, true}); return; } @@ -1476,14 +1476,14 @@ QualType superClassType(superClassObjTy, 0); ObjCTypeParamList *superClassTypeParams = superClassDecl->getTypeParamList(); if (!superClassTypeParams) { - CachedSuperClassType.setPointerAndInt( - superClassType->castAs(), true); + CachedSuperClassAndIsKindOf.setPointer({ + superClassType->castAs(), true}); return; } // If the superclass reference is unspecialized, return it. if (superClassObjTy->isUnspecialized()) { - CachedSuperClassType.setPointerAndInt(superClassObjTy, true); + CachedSuperClassAndIsKindOf.setPointer({superClassObjTy, true}); return; } @@ -1491,8 +1491,8 @@ // parameters in the superclass reference to substitute. ObjCTypeParamList *typeParams = classDecl->getTypeParamList(); if (!typeParams) { - CachedSuperClassType.setPointerAndInt( - superClassType->castAs(), true); + CachedSuperClassAndIsKindOf.setPointer({ + superClassType->castAs(), true}); return; } @@ -1502,20 +1502,19 @@ QualType unspecializedSuper = classDecl->getASTContext().getObjCInterfaceType( superClassObjTy->getInterface()); - CachedSuperClassType.setPointerAndInt( - unspecializedSuper->castAs(), - true); + CachedSuperClassAndIsKindOf.setPointer({ + unspecializedSuper->castAs(), true}); return; } // Substitute the provided type arguments into the superclass type. ArrayRef typeArgs = getTypeArgs(); assert(typeArgs.size() == typeParams->size()); - CachedSuperClassType.setPointerAndInt( + CachedSuperClassAndIsKindOf.setPointer({ superClassType.substObjCTypeArgs(classDecl->getASTContext(), typeArgs, ObjCSubstitutionContext::Superclass) ->castAs(), - true); + true}); } const ObjCInterfaceType *ObjCObjectPointerType::getInterfaceType() const {